ms-time-sheet 0.0.3 → 0.0.5

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.
@@ -713,183 +713,6 @@ class TimeSheetComponent {
713
713
  preventManualLogsTooltipHide() {
714
714
  // Prevent tooltip from hiding when mouse enters
715
715
  }
716
- // Pivot mode functionality
717
- togglePivotMode() {
718
- this.pivotMode = !this.pivotMode;
719
- if (this.pivotMode) {
720
- this.enablePivotMode();
721
- }
722
- else {
723
- this.disablePivotMode();
724
- }
725
- this.cdr.markForCheck();
726
- }
727
- // View mode functionality
728
- toggleViewMode(mode) {
729
- this.viewMode = mode;
730
- this.applyViewMode();
731
- this.cdr.markForCheck();
732
- }
733
- applyViewMode() {
734
- // Apply different configurations based on view mode
735
- switch (this.viewMode) {
736
- case 'standard':
737
- this.rowHeight = 44;
738
- this.headerRowHeight = 44;
739
- this.showColumnsGrouping = false;
740
- this.showFilterRow = false;
741
- break;
742
- case 'compact':
743
- this.rowHeight = 32;
744
- this.headerRowHeight = 32;
745
- this.showColumnsGrouping = false;
746
- this.showFilterRow = false;
747
- break;
748
- case 'detailed':
749
- this.rowHeight = 44;
750
- this.headerRowHeight = 44;
751
- this.showColumnsGrouping = true;
752
- this.showFilterRow = true;
753
- break;
754
- case 'timeline':
755
- this.rowHeight = 60;
756
- this.headerRowHeight = 44;
757
- this.showColumnsGrouping = false;
758
- this.showFilterRow = false;
759
- break;
760
- case 'calendar':
761
- this.rowHeight = 80;
762
- this.headerRowHeight = 44;
763
- this.showColumnsGrouping = false;
764
- this.showFilterRow = false;
765
- break;
766
- case 'card':
767
- this.rowHeight = 120;
768
- this.headerRowHeight = 44;
769
- this.showColumnsGrouping = false;
770
- this.showFilterRow = false;
771
- break;
772
- case 'heatmap':
773
- this.rowHeight = 40;
774
- this.headerRowHeight = 44;
775
- this.showColumnsGrouping = false;
776
- this.showFilterRow = false;
777
- break;
778
- }
779
- // Refresh the grid
780
- this.updateFlattenedData();
781
- this.computeViewportRows();
782
- this.updateVisibleRowsOptimized(0);
783
- }
784
- enablePivotMode() {
785
- // Transform data for pivot view
786
- // This would involve restructuring the data to show aggregated/summarized information
787
- console.log('Pivot mode enabled');
788
- }
789
- disablePivotMode() {
790
- // Restore original data structure
791
- console.log('Pivot mode disabled');
792
- }
793
- // Theme switching methods
794
- applyTheme(themeName) {
795
- const theme = this.themes[themeName];
796
- if (!theme)
797
- return;
798
- // Apply theme properties to component inputs
799
- this.bodyBackgroundColor = theme.bodyBackgroundColor;
800
- this.headerBackgroundColor = theme.headerBackgroundColor;
801
- this.bodyTextColor = theme.bodyTextColor;
802
- this.headerTextColor = theme.headerTextColor;
803
- this.checkboxesBackgroundColor = theme.checkboxesBackgroundColor;
804
- this.dropdownsBackgroundColor = theme.dropdownsBackgroundColor;
805
- this.rowHoverColor = theme.rowHoverColor;
806
- this.selectedRowsBackgroundColor = theme.selectedRowsBackgroundColor;
807
- this.evenRowsBackgroundColor = theme.evenRowsBackgroundColor;
808
- this.oddRowsBackgroundColor = theme.oddRowsBackgroundColor;
809
- this.leftPinnedBackgroundColor = theme.leftPinnedBackgroundColor;
810
- this.rightPinnedBackgroundColor = theme.rightPinnedBackgroundColor;
811
- this.sidemenuBackgroundColor = theme.sidemenuBackgroundColor;
812
- this.currentTheme = themeName;
813
- // Apply data-theme attribute to the component host element for global theme application
814
- const hostElement = this.elementRef.nativeElement;
815
- hostElement.setAttribute('data-theme', themeName);
816
- // Force re-render of the component to apply theme changes
817
- this.cdr.detectChanges();
818
- // Add a small delay to ensure DOM updates are complete
819
- setTimeout(() => {
820
- this.cdr.detectChanges();
821
- }, 10);
822
- }
823
- // Apply theme from backend config or default theme
824
- applyBackendThemeOrDefault() {
825
- // Check if backend has provided theme colors
826
- const hasBackendTheme = this.bodyBackgroundColor || this.headerBackgroundColor ||
827
- this.bodyTextColor || this.headerTextColor;
828
- if (hasBackendTheme) {
829
- // Backend theme is already applied via inputs, no need to apply default
830
- this.currentTheme = 'backend';
831
- }
832
- else {
833
- // Apply default theme
834
- this.applyTheme(this.currentTheme);
835
- }
836
- }
837
- applyCustomTheme() {
838
- // Generate a custom theme based on the selected color
839
- const baseColor = this.customThemeColor;
840
- const isLightColor = this.isLightColor(baseColor);
841
- // Calculate complementary colors
842
- const headerBg = this.adjustBrightness(baseColor, isLightColor ? -20 : 20);
843
- const textColor = isLightColor ? '#000000' : '#ffffff';
844
- const hoverColor = this.adjustBrightness(baseColor, isLightColor ? 10 : -10);
845
- // Apply custom theme properties
846
- this.bodyBackgroundColor = baseColor;
847
- this.headerBackgroundColor = headerBg;
848
- this.bodyTextColor = textColor;
849
- this.headerTextColor = textColor;
850
- this.checkboxesBackgroundColor = headerBg;
851
- this.dropdownsBackgroundColor = baseColor;
852
- this.rowHoverColor = `rgba(${this.hexToRgb(hoverColor)}, 0.1)`;
853
- this.selectedRowsBackgroundColor = this.adjustBrightness(baseColor, isLightColor ? 20 : -20);
854
- this.evenRowsBackgroundColor = this.adjustBrightness(baseColor, isLightColor ? 5 : -5);
855
- this.oddRowsBackgroundColor = baseColor;
856
- this.leftPinnedBackgroundColor = headerBg;
857
- this.rightPinnedBackgroundColor = headerBg;
858
- this.sidemenuBackgroundColor = headerBg;
859
- this.currentTheme = 'custom';
860
- // Apply data-theme attribute
861
- const hostElement = this.elementRef.nativeElement;
862
- hostElement.setAttribute('data-theme', 'custom');
863
- this.cdr.detectChanges();
864
- setTimeout(() => {
865
- this.cdr.detectChanges();
866
- }, 10);
867
- }
868
- isLightColor(color) {
869
- const rgb = this.hexToRgb(color);
870
- const brightness = (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
871
- return brightness > 128;
872
- }
873
- adjustBrightness(color, amount) {
874
- const rgb = this.hexToRgb(color);
875
- const adjust = (val) => Math.max(0, Math.min(255, val + amount));
876
- return `rgb(${adjust(rgb.r)}, ${adjust(rgb.g)}, ${adjust(rgb.b)})`;
877
- }
878
- hexToRgb(hex) {
879
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
880
- return result ? {
881
- r: parseInt(result[1], 16),
882
- g: parseInt(result[2], 16),
883
- b: parseInt(result[3], 16)
884
- } : { r: 0, g: 0, b: 0 };
885
- }
886
- toggleThemeSelector() {
887
- this.showThemeSelector = !this.showThemeSelector;
888
- }
889
- selectTheme(themeName) {
890
- this.applyTheme(themeName);
891
- this.showThemeSelector = false;
892
- }
893
716
  // Method to transform status strings
894
717
  transformStatus(status) {
895
718
  if (!status)
@@ -1136,50 +959,12 @@ class TimeSheetComponent {
1136
959
  this.showActionsDropDown = false;
1137
960
  this.sideMenuVisible = false;
1138
961
  this.pivotMode = false;
1139
- // View modes
1140
- this.viewMode = 'standard';
1141
962
  this.columnSearch = '';
1142
963
  this.expandAllAccordians = true;
1143
964
  this.currentOpenedSideMenue = null;
1144
965
  // Global detail sort properties
1145
966
  this.detailSortField = null;
1146
967
  this.detailSortOrder = null;
1147
- // Theme configurations
1148
- this.themes = {
1149
- white: {
1150
- bodyBackgroundColor: '#ffffff',
1151
- headerBackgroundColor: '#f8f9fa',
1152
- bodyTextColor: '#000000',
1153
- headerTextColor: '#000000',
1154
- checkboxesBackgroundColor: '#f8f9fa',
1155
- dropdownsBackgroundColor: '#ffffff',
1156
- rowHoverColor: 'rgba(0, 123, 255, 0.1)',
1157
- selectedRowsBackgroundColor: '#e3f2fd',
1158
- evenRowsBackgroundColor: '#f8f9fa',
1159
- oddRowsBackgroundColor: '#ffffff',
1160
- leftPinnedBackgroundColor: '#f0f0f0',
1161
- rightPinnedBackgroundColor: '#f0f0f0',
1162
- sidemenuBackgroundColor: '#f0f0f0'
1163
- },
1164
- blue: {
1165
- bodyBackgroundColor: '#f0f8ff',
1166
- headerBackgroundColor: '#e6f3ff',
1167
- bodyTextColor: '#1e3a5f',
1168
- headerTextColor: '#1e3a5f',
1169
- checkboxesBackgroundColor: '#e6f3ff',
1170
- dropdownsBackgroundColor: '#ffffff',
1171
- rowHoverColor: 'rgba(30, 58, 95, 0.1)',
1172
- selectedRowsBackgroundColor: '#cce5ff',
1173
- evenRowsBackgroundColor: '#f0f8ff',
1174
- oddRowsBackgroundColor: '#ffffff',
1175
- leftPinnedBackgroundColor: '#e6f3ff',
1176
- rightPinnedBackgroundColor: '#e6f3ff',
1177
- sidemenuBackgroundColor: '#e6f3ff'
1178
- }
1179
- };
1180
- this.currentTheme = 'white';
1181
- this.showThemeSelector = false;
1182
- this.customThemeColor = '#ffffff';
1183
968
  this.originalColumns = [];
1184
969
  this.originalDataSet = [];
1185
970
  this.activeTopButton = '';
@@ -1678,6 +1463,7 @@ class TimeSheetComponent {
1678
1463
  this.printClicked = new EventEmitter();
1679
1464
  this.exportClicked = new EventEmitter();
1680
1465
  this.exportDailyClicked = new EventEmitter();
1466
+ this.deleteClicked = new EventEmitter();
1681
1467
  // isShortLeavePopoverVisible = false;
1682
1468
  // currentShortLeaveData: any[] = [];
1683
1469
  // shortLeaveTooltipPosition = { x: 0, y: 0 };
@@ -1709,7 +1495,7 @@ class TimeSheetComponent {
1709
1495
  };
1710
1496
  this.genericEvent.emit(eventData);
1711
1497
  // Apply theme from backend config if provided, otherwise use default theme
1712
- this.applyBackendThemeOrDefault();
1498
+ // Theme functionality removed
1713
1499
  // // Subscribe to loading state from service
1714
1500
  // this.timeSheetService.loading$.subscribe(loading => {
1715
1501
  // this.loading = loading;
@@ -2099,17 +1885,7 @@ class TimeSheetComponent {
2099
1885
  }));
2100
1886
  needsUpdate = true;
2101
1887
  }
2102
- // Handle theme-related input changes
2103
- if (changes['bodyBackgroundColor'] || changes['headerBackgroundColor'] ||
2104
- changes['bodyTextColor'] || changes['headerTextColor'] ||
2105
- changes['checkboxesBackgroundColor'] || changes['dropdownsBackgroundColor'] ||
2106
- changes['rowHoverColor'] || changes['selectedRowsBackgroundColor'] ||
2107
- changes['evenRowsBackgroundColor'] || changes['oddRowsBackgroundColor'] ||
2108
- changes['leftPinnedBackgroundColor'] || changes['rightPinnedBackgroundColor'] ||
2109
- changes['sidemenuBackgroundColor']) {
2110
- this.currentTheme = 'backend';
2111
- needsUpdate = true;
2112
- }
1888
+ // Handle theme-related input changes - theme functionality removed
2113
1889
  if (needsUpdate) {
2114
1890
  this.cdr.markForCheck();
2115
1891
  }
@@ -4307,7 +4083,7 @@ class TimeSheetComponent {
4307
4083
  }
4308
4084
  }
4309
4085
  openFilteronThreeDotsClick(col) {
4310
- if (col.type == 'image')
4086
+ if (col.type == 'image' || col.type === '')
4311
4087
  return;
4312
4088
  this.selectedColumnForFilter = col;
4313
4089
  this.isThreeDotsFilterOpen = true;
@@ -4315,7 +4091,19 @@ class TimeSheetComponent {
4315
4091
  this.currentFilterSelectedIds.clear();
4316
4092
  const savedIds = col?.query?._ids || [];
4317
4093
  savedIds.forEach((id) => this.currentFilterSelectedIds.add(id));
4318
- this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option));
4094
+ // Use column_dropdown_value if available, otherwise fallback to column_data
4095
+ let dropdownData = this.selectedColumnForFilter?.column_dropdown_value || this.selectedColumnForFilter?.column_data || [];
4096
+ // Normalize string arrays to object format
4097
+ if (dropdownData.length > 0 && typeof dropdownData[0] === 'string') {
4098
+ dropdownData = dropdownData.map((item) => ({
4099
+ _id: item,
4100
+ value: item,
4101
+ __typename: 'column_dropdown_value'
4102
+ }));
4103
+ }
4104
+ // Ensure column_dropdown_value is set for UI to use
4105
+ this.selectedColumnForFilter.column_dropdown_value = dropdownData;
4106
+ this.selectedFilterOptions = dropdownData.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option?.value || option));
4319
4107
  setTimeout(() => {
4320
4108
  this.filterMenueSearchInput.nativeElement.focus();
4321
4109
  }, 100);
@@ -4332,6 +4120,9 @@ class TimeSheetComponent {
4332
4120
  }
4333
4121
  }
4334
4122
  openFilter(col) {
4123
+ // Prevent filter opening for columns with empty type or image type
4124
+ if (col.type === '' || col.type === 'image')
4125
+ return;
4335
4126
  this.activeFilterCell = col;
4336
4127
  this.activeCol = null;
4337
4128
  this.isFilterOpen = true;
@@ -4340,7 +4131,17 @@ class TimeSheetComponent {
4340
4131
  this.currentFilterSelectedIds.clear();
4341
4132
  const savedIds = col?.query?._ids || [];
4342
4133
  savedIds.forEach((id) => this.currentFilterSelectedIds.add(id));
4343
- this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value?.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option));
4134
+ // Use column_dropdown_value if available, otherwise fallback to column_data
4135
+ let dropdownData = this.selectedColumnForFilter?.column_dropdown_value || this.selectedColumnForFilter?.column_data || [];
4136
+ // Normalize string arrays to object format
4137
+ if (dropdownData.length > 0 && typeof dropdownData[0] === 'string') {
4138
+ dropdownData = dropdownData.map((item) => ({
4139
+ _id: item,
4140
+ value: item,
4141
+ __typename: 'column_dropdown_value'
4142
+ }));
4143
+ }
4144
+ this.selectedFilterOptions = dropdownData.filter((option) => this.currentFilterSelectedIds.has(option?.id || option?._id || option?.value || option));
4344
4145
  }
4345
4146
  else if (['string', 'number', 'date'].includes(col.type)) {
4346
4147
  this.firstCondition = col?.query?.first_condition || 'contain';
@@ -4362,14 +4163,24 @@ class TimeSheetComponent {
4362
4163
  this.activeTopButton = '';
4363
4164
  }
4364
4165
  toggleSelectionInFilter(option) {
4365
- const id = option.id || option._id || option;
4166
+ const id = option.id || option._id || option?.value || option;
4366
4167
  if (this.currentFilterSelectedIds.has(id)) {
4367
4168
  this.currentFilterSelectedIds.delete(id);
4368
4169
  }
4369
4170
  else {
4370
4171
  this.currentFilterSelectedIds.add(id);
4371
4172
  }
4372
- this.selectedFilterOptions = this.selectedColumnForFilter?.column_dropdown_value.filter((option) => this.currentFilterSelectedIds.has(option.id || option._id || option));
4173
+ // Use column_dropdown_value if available, otherwise fallback to column_data
4174
+ let dropdownData = this.selectedColumnForFilter?.column_dropdown_value || this.selectedColumnForFilter?.column_data || [];
4175
+ // Normalize string arrays to object format
4176
+ if (dropdownData.length > 0 && typeof dropdownData[0] === 'string') {
4177
+ dropdownData = dropdownData.map((item) => ({
4178
+ _id: item,
4179
+ value: item,
4180
+ __typename: 'column_dropdown_value'
4181
+ }));
4182
+ }
4183
+ this.selectedFilterOptions = dropdownData.filter((option) => this.currentFilterSelectedIds.has(option.id || option._id || option?.value || option));
4373
4184
  this.cdr.detectChanges();
4374
4185
  }
4375
4186
  resetFilterChanges() {
@@ -4436,6 +4247,15 @@ class TimeSheetComponent {
4436
4247
  this.filterOptions.emit(filteredColumns);
4437
4248
  }
4438
4249
  applyFilterFromFilterRow(column) {
4250
+ // Ensure default conditions are set before applying filter
4251
+ if (column.query) {
4252
+ if (!column.query.first_condition) {
4253
+ column.query.first_condition = 'contain';
4254
+ }
4255
+ if (!column.query.second_condition) {
4256
+ column.query.second_condition = 'contain';
4257
+ }
4258
+ }
4439
4259
  const filter = {
4440
4260
  field: column.field,
4441
4261
  search: column.search,
@@ -4937,9 +4757,13 @@ class TimeSheetComponent {
4937
4757
  else {
4938
4758
  val = value;
4939
4759
  }
4940
- const field = column?.field?.toLowerCase();
4760
+ const field = column?.field;
4941
4761
  const status = val?.toString().toLowerCase();
4942
- if (field === 'status' || field === 'account_status' || field === 'availStatus' || field === 'is_custom_grade') {
4762
+ // Skip badge classes for status and attendanceStatus fields as they're handled separately in template
4763
+ if (field === 'status' || field === 'attendanceStatus') {
4764
+ return '';
4765
+ }
4766
+ if (field === 'account_status' || field === 'availStatus' || field === 'is_custom_grade') {
4943
4767
  return STATUSES_BADGE_MAP[status] || 'badge badge-secondary';
4944
4768
  }
4945
4769
  return '';
@@ -7365,6 +7189,7 @@ class TimeSheetComponent {
7365
7189
  onPrintClick() { this.printClicked.emit(); }
7366
7190
  onExportClick() { this.exportClicked.emit(); }
7367
7191
  onExportDailyClick() { this.exportDailyClicked.emit(); }
7192
+ onDeleteClick() { this.deleteClicked.emit(); }
7368
7193
  get areDatesSelectedAndEqual() {
7369
7194
  if (!this.bsRangeValue || this.bsRangeValue.length < 2) {
7370
7195
  return false;
@@ -7496,11 +7321,49 @@ class TimeSheetComponent {
7496
7321
  return parts[0][0] + (parts[1]?.[0] || '').toUpperCase();
7497
7322
  }
7498
7323
  getStatusBadgeClass(status) {
7499
- switch (status?.toLowerCase()) {
7500
- case 'present': return 'bg-success';
7501
- case 'absent': return 'bg-danger';
7502
- case 'late': return 'bg-warning';
7503
- default: return 'bg-secondary';
7324
+ const transformed = this.transformStatus(status)?.toLowerCase();
7325
+ switch (transformed) {
7326
+ case 'clocked in':
7327
+ return { 'badge': true, 'bg-success': true };
7328
+ case 'absent':
7329
+ return { 'badge': true, 'bg-danger': true };
7330
+ case 'on leave':
7331
+ return { 'badge': true, 'bg-warning': true };
7332
+ case 'holiday':
7333
+ return { 'badge': true, 'bg-info': true };
7334
+ case 'clocked out':
7335
+ return { 'badge': true, 'bg-secondary': true };
7336
+ default:
7337
+ return { 'badge': true, 'bg-light': true, 'text-dark': true };
7338
+ }
7339
+ }
7340
+ getAttendanceStatusBadgeClass(status) {
7341
+ const transformed = this.transformStatus(status)?.toLowerCase();
7342
+ switch (transformed) {
7343
+ case 'absent':
7344
+ return { 'badge': true, 'bg-danger': true };
7345
+ case 'block':
7346
+ return { 'badge': true, 'bg-dark': true };
7347
+ case 'earlyin':
7348
+ return { 'badge': true, 'bg-warning': true };
7349
+ case 'lateout':
7350
+ return { 'badge': true, 'bg-warning': true };
7351
+ case 'earlyout':
7352
+ return { 'badge': true, 'bg-warning': true };
7353
+ case 'lateness':
7354
+ return { 'badge': true, 'bg-warning': true };
7355
+ case 'leave':
7356
+ return { 'badge': true, 'bg-secondary': true };
7357
+ case 'onshortleave':
7358
+ return { 'badge': true, 'bg-info': true };
7359
+ case 'misspunchout':
7360
+ return { 'badge': true, 'bg-danger': true };
7361
+ case 'ontimeout':
7362
+ return { 'badge': true, 'bg-success': true };
7363
+ case 'publicholiday':
7364
+ return { 'badge': true, 'bg-primary': true };
7365
+ default:
7366
+ return { 'badge': true, 'bg-light': true, 'text-dark': true };
7504
7367
  }
7505
7368
  }
7506
7369
  // Heatmap View Methods
@@ -7563,7 +7426,7 @@ class TimeSheetComponent {
7563
7426
  return `${day.date.toDateString()}: ${day.activity.toFixed(1)} hours`;
7564
7427
  }
7565
7428
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimeSheetComponent, deps: [{ token: i0.Injector }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); }
7566
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeSheetComponent, isStandalone: true, selector: "time-sheet", inputs: { paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", isSingleDay: "isSingleDay", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", enableAccordionShadow: "enableAccordionShadow", enableAccordionSeparators: "enableAccordionSeparators", enableRowShading: "enableRowShading", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBAckgroundColor: "nestedTableHeaderBAckgroundColor", tableView: "tableView", columnThreedotsMunuConfig: "columnThreedotsMunuConfig", timezonePrefs: "timezonePrefs", enableProgressiveLoading: "enableProgressiveLoading", progressiveChunkSize: "progressiveChunkSize", progressiveDelay: "progressiveDelay", enableInfiniteScroll: "enableInfiniteScroll", hasMoreData: "hasMoreData", loadingMore: "loadingMore", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", loadMoreData: "loadMoreData", changeLayout: "changeLayout", filterOptions: "filterOptions", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing", loadMore: "loadMore", emailClicked: "emailClicked", addAttendanceClicked: "addAttendanceClicked", backPayClicked: "backPayClicked", grandTotalClicked: "grandTotalClicked", printClicked: "printClicked", exportClicked: "exportClicked", exportDailyClicked: "exportDailyClicked" }, 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\" [attr.data-theme]=\"currentTheme\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n \r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- View Mode Buttons -->\r\n <div class=\"btn-group me-2\" role=\"group\" aria-label=\"View modes\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'standard'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'standard'\"\r\n (click)=\"toggleViewMode('standard')\"\r\n title=\"Standard View\"\r\n >\r\n <i class=\"bi bi-grid\"></i>\r\n </button>\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'compact'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'compact'\"\r\n (click)=\"toggleViewMode('compact')\"\r\n title=\"Compact View\"\r\n >\r\n <i class=\"bi bi-list\"></i>\r\n </button> -->\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'detailed'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'detailed'\"\r\n (click)=\"toggleViewMode('detailed')\"\r\n title=\"Detailed View\"\r\n >\r\n <i class=\"bi bi-table\"></i>\r\n </button> -->\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'timeline'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'timeline'\"\r\n (click)=\"toggleViewMode('timeline')\"\r\n title=\"Timeline View\"\r\n >\r\n <i class=\"bi bi-clock-history\"></i>\r\n </button> -->\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'calendar'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'calendar'\"\r\n (click)=\"toggleViewMode('calendar')\"\r\n title=\"Calendar View\"\r\n >\r\n <i class=\"bi bi-calendar\"></i>\r\n </button> -->\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'card'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'card'\"\r\n (click)=\"toggleViewMode('card')\"\r\n title=\"Card View\"\r\n >\r\n <i class=\"bi bi-card-text\"></i>\r\n </button>\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'heatmap'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'heatmap'\"\r\n (click)=\"toggleViewMode('heatmap')\"\r\n title=\"Heatmap View\"\r\n >\r\n <i class=\"bi bi-fire\"></i>\r\n </button> -->\r\n </div>\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <!-- Theme Selector Button -->\r\n <div class=\"position-relative\">\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"toggleThemeSelector()\"\r\n title=\"Change Theme\"\r\n >\r\n <i class=\"bi bi-palette\"></i>\r\n </a>\r\n\r\n <!-- Color Picker -->\r\n <div\r\n *ngIf=\"showThemeSelector\"\r\n class=\"position-absolute mt-1 shadow rounded-3 bg-white border\"\r\n style=\"z-index: 1050; right: 0; min-width: 200px;\"\r\n >\r\n <div class=\"p-2\">\r\n <div class=\"fw-semibold mb-2 px-2\">Select Theme Color</div>\r\n <div class=\"d-flex flex-column gap-2\">\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm\"\r\n [class.btn-outline-primary]=\"currentTheme === 'white'\"\r\n (click)=\"selectTheme('white')\"\r\n style=\"flex: 1;\"\r\n >\r\n <i class=\"bi bi-sun me-2\"></i>Light\r\n </button>\r\n <button\r\n class=\"btn btn-sm\"\r\n [class.btn-outline-primary]=\"currentTheme === 'blue'\"\r\n (click)=\"selectTheme('blue')\"\r\n style=\"flex: 1;\"\r\n >\r\n <i class=\"bi bi-droplet me-2\"></i>Blue\r\n </button>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <label class=\"form-label mb-0\" style=\"font-size: 12px;\">Custom:</label>\r\n <input\r\n type=\"color\"\r\n class=\"form-control form-control-sm\"\r\n [(ngModel)]=\"customThemeColor\"\r\n (change)=\"applyCustomTheme()\"\r\n style=\"width: 40px; height: 30px; padding: 0; border: none; cursor: pointer;\"\r\n />\r\n <span class=\"text-muted\" style=\"font-size: 11px;\">{{ customThemeColor }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Email Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"onEmailClick()\"\r\n title=\"Email\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/smsIcon.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Email</span>\r\n</a>\r\n\r\n<!-- Add Attendance Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onAddAttendanceClick()\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/addAttendenceIcon.svg'\"\r\n class=\"svg-icon svg-icon-2 pe-2\"\r\n ></span>\r\n Add Attendance\r\n</a>\r\n\r\n<!-- Back Pay Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onBackPayClick()\"\r\n title=\"Back Pay\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/back pay.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Back pay</span>\r\n</a>\r\n\r\n<!-- Grand Total Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onGrandTotalClick()\"\r\n title=\"Grand Total\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/grandtotal.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Grand totel</span>\r\n</a>\r\n\r\n<!-- Print Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onPrintClick()\"\r\n title=\"Print\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/printIcon.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Print</span>\r\n</a>\r\n\r\n<!-- Export Button (Multi-day) -->\r\n<a\r\n *ngIf=\"!isSingleDay\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onExportClick()\"\r\n title=\"Export\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/general/export.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Export</span>\r\n</a>\r\n\r\n<!-- Export Daily Timesheet (Single-day) -->\r\n<a\r\n *ngIf=\"isSingleDay\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onExportDailyClick()\"\r\n title=\"Export Daily Timesheet\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/general/export.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Export Daily Timesheet</span>\r\n</a>\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n<div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 2px;\r\n top: 2px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n</div>\r\n<!-- <div\r\n class=\"cursor-pointer\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n</div> -->\r\n<div\r\n class=\"cursor-pointer\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a class=\"dropdown-item\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a class=\"dropdown-item\" (click)=\"downloadCsv()\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Download as CSV\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div class=\"d-flex gap-2 align-items-center me-5\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n \r\n\r\n \r\n <div class=\"position-relative d-inline-block ms-5\">\r\n \r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n \r\n <!-- Calendar Icon -->\r\n\r\n <!-- <div class=\"icon-container position-absolute end-0 top-50 translate-middle-y me-2\"\r\n (click)=\"togglePicker(picker)\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/calendar.svg'\"\r\n class=\"data-grid-svg-icon top-icon\"\r\n style=\"cursor: pointer;\"\r\n ></span>\r\n </div> -->\r\n <div class=\"icon-container position-absolute end-0 top-50 translate-middle-y d-flex align-items-center\">\r\n <i\r\n class=\"bi bi-calendar me-1\"\r\n style=\"cursor: pointer;\"\r\n (click)=\"togglePicker(picker)\"\r\n ></i>\r\n <!-- Clear Icon -->\r\n <i\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"bi bi-x-circle text-danger\"\r\n style=\"cursor: pointer;\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date\"\r\n ></i>\r\n </div>\r\n \r\n </div>\r\n\r\n </div>\r\n <div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"65\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n ></div>\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterHeaderScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"openThreeDotsMenu($event, 'group')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"onResizeGroupBox($event)\"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <!-- <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div [style.width.px]=\"30\"></div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'previewRightPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet.length && !loading\"\r\n >\r\n No Record Found\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n <div\r\n *ngIf=\"viewMode === 'card'\"\r\n class=\"card-view-container p-3\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n >\r\n <div class=\"row g-3\">\r\n <div\r\n *ngFor=\"let row of dataSet; let i = index; trackBy: trackById\"\r\n class=\"col-xl-4 col-lg-6 col-md-6 col-sm-12\"\r\n >\r\n <div class=\"card h-100 shadow-sm attendance-card\" [class.expanded]=\"row.isCardExpanded\">\r\n <!-- Card Header -->\r\n <div class=\"card-header d-flex align-items-center p-3\">\r\n <div class=\"employee-avatar me-3\">\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <img\r\n [width]=\"40\"\r\n [height]=\"40\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"avatar\"\r\n class=\"rounded-circle\"\r\n />\r\n </ng-container>\r\n <ng-template #placeholder>\r\n <div\r\n class=\"avatar-placeholder rounded-circle d-flex align-items-center justify-content-center text-white fw-bold\"\r\n [style.width.px]=\"40\"\r\n [style.height.px]=\"40\"\r\n [style.fontSize.px]=\"16\"\r\n [style.backgroundColor]=\"getAvatarColor(row?.User?.full_name || row?.full_name || row?.name)\"\r\n >\r\n {{ getInitialss(row?.User?.full_name || row?.full_name || row?.name) }}\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <h6 class=\"mb-1 fw-bold\">{{ row?.User?.full_name || row?.full_name || row?.name || 'N/A' }}</h6>\r\n <small class=\"text-muted\">{{ row?.attendanceDate | date:'mediumDate' }}</small>\r\n </div>\r\n <div class=\"card-actions\">\r\n <button\r\n class=\"btn btn-sm btn-outline-primary\"\r\n (click)=\"row.isCardExpanded = !row.isCardExpanded\"\r\n [title]=\"row.isCardExpanded ? 'Collapse' : 'Expand'\"\r\n >\r\n <i class=\"bi\" [class]=\"row.isCardExpanded ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Card Body -->\r\n <div class=\"card-body p-3\">\r\n <!-- Basic Attendance Info -->\r\n <div class=\"row g-2 mb-3\">\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock In</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_in_time ? (row.clock_in_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock Out</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_out_time ? (row.clock_out_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Total Hours</small>\r\n <span class=\"fw-semibold\">{{ calculateTotalHours(row) }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Status</small>\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(row?.attendanceStatus)\">{{ row?.attendanceStatus || 'Unknown' }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Expandable Details -->\r\n <div class=\"card-details\" *ngIf=\"row.isCardExpanded\">\r\n <hr class=\"my-3\">\r\n\r\n <!-- All Column Data Section -->\r\n <div class=\"all-columns-section mb-3\">\r\n <h6 class=\"section-title mb-3\">\r\n <i class=\"bi bi-table me-2\"></i>All Details\r\n </h6>\r\n <div class=\"row g-2\">\r\n <ng-container *ngFor=\"let col of centerColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of leftPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of rightPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Breaks Section -->\r\n <div class=\"breaks-section mb-3\" *ngIf=\"row?.breaks?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-clock-history me-2\"></i>Breaks\r\n </h6>\r\n <div class=\"breaks-list\">\r\n <div\r\n *ngFor=\"let breakItem of row.breaks; let bIndex = index\"\r\n class=\"break-item p-2 border rounded mb-2\"\r\n [title]=\"getBreakTooltip(breakItem)\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ breakItem?.break_type?.data_value_name || ('Break ' + (bIndex + 1)) }}</small>\r\n <div class=\"text-muted small\">\r\n {{ breakItem?.break_in_time ? (breakItem.break_in_time | date:'shortTime') : '--:--' }} -\r\n {{ breakItem?.break_out_time ? (breakItem.break_out_time | date:'shortTime') : '--:--' }}\r\n </div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-info\">{{ breakItem?.break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Breaks Section -->\r\n <div class=\"short-breaks-section mb-3\" *ngIf=\"row?.short_breaks\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pause-circle me-2\"></i>Short Breaks\r\n </h6>\r\n <div class=\"short-break-item p-2 border rounded\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ row.short_breaks?.short_break_name || 'Quick Break' }}</small>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-warning\">{{ row.short_breaks?.short_break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Leave Section -->\r\n <div class=\"short-leave-section mb-3\" *ngIf=\"row?.short_leave?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-calendar-x me-2\"></i>Short Leave\r\n </h6>\r\n <div class=\"short-leave-list\">\r\n <div\r\n *ngFor=\"let leave of row.short_leave\"\r\n class=\"leave-item p-2 border rounded mb-2\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ leave?.leave_type || 'Leave' }}</small>\r\n <div class=\"text-muted small\">{{ leave?.minutes || 0 }} minutes</div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-danger\">Leave</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Manual Logs Section -->\r\n <div class=\"manual-logs-section mb-3\" *ngIf=\"row?.manually_logs?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pencil-square me-2\"></i>Manual Logs\r\n </h6>\r\n <button\r\n class=\"btn btn-sm btn-outline-info\"\r\n (click)=\"openManualLogsModal($event, row)\"\r\n title=\"View Manual Logs Details\"\r\n >\r\n <i class=\"bi bi-eye me-1\"></i>View Details\r\n </button>\r\n </div>\r\n\r\n <!-- Additional Details -->\r\n <div class=\"additional-details\">\r\n <div class=\"row g-2\">\r\n <div class=\"col-6\" *ngIf=\"row?.overtime_hours\">\r\n <small class=\"text-muted d-block\">Overtime</small>\r\n <span class=\"fw-semibold\">{{ row.overtime_hours }}h</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.late_minutes\">\r\n <small class=\"text-muted d-block\">Late Minutes</small>\r\n <span class=\"fw-semibold\">{{ row.late_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.early_departure_minutes\">\r\n <small class=\"text-muted d-block\">Early Departure</small>\r\n <span class=\"fw-semibold\">{{ row.early_departure_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.message\">\r\n <small class=\"text-muted d-block\">Remarks</small>\r\n <span class=\"fw-semibold text-truncate d-block\" [title]=\"row.message\">{{ row.message }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table View -->\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n *ngIf=\"dataSet.length && viewMode !== 'card'\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length) + (hasMoreData ? 1000 : 0)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onHorizintalFakeScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, child)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"onResizeColumn($event, child)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div class=\"group-column-wrapper\">\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"onResizeColumn($event, col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"65\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"65\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n </div>\r\n <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4 border-right\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (click)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on me-2 text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <div class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeavePopover($event, d)\"\r\n (mouseleave)=\"hideShortLeavePopover()\">\r\n <span class=\"d-block\"\r\n [style.min-width.%]=\"(d.short_leave && d.short_leave.length > 0) ? d.short_leave[0].short_leave_time_percentage : 0\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ (d.short_leave && d.short_leave.length > 0) ? d.short_leave[0].short_leave_time_percentage : 0 }}%</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: inline-flex; gap: 4px; align-items: center; height: 100%; justify-content: center; text-align: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { \r\n break_duration: 0, \r\n break_type: { data_value_name: 'No Break' }, \r\n breakInstatus: 'None',\r\n break_in_time: null,\r\n break_out_time: null\r\n })\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n 0m\r\n </div>\r\n</ng-template>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeavePopover($event, d)\"\r\n (mouseleave)=\"hideShortLeavePopover()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <!-- <ng-template #noShortLeaveDetail>\r\n <div class=\"circle-value\">0%</div>\r\n </ng-template> -->\r\n </div>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (click)=\"showManualLogsTooltip($event, row, d)\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"rowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (click)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on me-2 text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveLeft\">\r\n <div class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\">\r\n <span class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <!-- <ng-template #noShortLeaveLeft>\r\n <div class=\"circle-value\">0%</div>\r\n </ng-template> -->\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col.type === 'date'\r\n ? (getNestedValue(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <div class=\"d-flex justify-content-center align-items-center flex-wrap gap-1\">\r\n <span *ngFor=\"let breakItem of getNestedValue(row, 'breaks'); trackBy: trackById\" class=\"popover__wrapper\" (mouseenter)=\"showBreakTooltip($event, breakItem)\" (mouseleave)=\"hideBreakTooltip()\">\r\n <span class=\"circle-value badge-outline break-on text-center\" [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div class=\"circle-value text-muted text-center\" (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\" (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [style.backgroundColor]=\"getBreakColor(row.short_breaks.type)\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div class=\"circle-value text-center\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\" (mouseleave)=\"hideShortBreakTooltip()\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\" (mouseenter)=\"showShortLeavePopover($event, row)\" (mouseleave)=\"hideShortLeavePopover()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"(row.short_leave && row.short_leave.length > 0) ? row.short_leave[0].short_leave_time_percentage : 0\" style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ (row.short_leave && row.short_leave.length > 0) ? row.short_leave[0].short_leave_time_percentage : 0 }}%</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? (getNestedValue(row, col.field) | date: dateFormat)\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\" (mouseleave)=\"hideManualLogsTooltip()\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon -->\r\n <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> In: {{ currentBreakTooltip.break_in_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> Out: {{ currentBreakTooltip.break_out_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentBreakTooltip.break_duration }} min</div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> Start: {{ currentShortBreakTooltip.start_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> End: {{ currentShortBreakTooltip.end_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentShortBreakTooltip.short_break_duration }} min</div>\r\n </div>\r\n</div>\r\n\r\n\r\n<!-- Short Leave Popover (Detail Rows) -->\r\n<div\r\n *ngIf=\"isShortLeavePopoverVisible\"\r\n class=\"popver_content_progress_bar\"\r\n [style.position]=\"'fixed'\"\r\n [style.top.px]=\"shortLeaveTooltipPosition.y + 10\"\r\n [style.left.px]=\"shortLeaveTooltipPosition.x\"\r\n style=\"z-index: 1000; background: white; border: 1px solid #ddd; border-radius: 6px; padding: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); width: 250px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area\">\r\n <div class=\"table-responsive iis-scrollbar table-container\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-3\" style=\"font-size: xx-small;\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 20%;\">Leave Type</th>\r\n <th class=\"center\">Start</th>\r\n <th class=\"center\">End</th>\r\n <th class=\"center\">Duration</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let leave of currentShortLeaveData\">\r\n <td class=\"center\">{{ leave.leave_type || 'Short Leave' }}</td>\r\n <td class=\"center\">{{ leave.star_time || leave.start_time || '\u2013' }}</td>\r\n <td class=\"center\">{{ leave.end_time || '\u2013' }}</td>\r\n <td class=\"center\">{{ leave.hours }}H {{ leave.minutes % 60 }}M</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" [class.visually-hidden]=\"isMenueHidden\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col.query.first_value\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container *ngIf=\"col.query?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n />\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n</div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.firt_value\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.firt_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation();\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save Preset\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div class=\"\">\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <span\r\n *ngIf=\"!tableFilterViewId\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"clearAllFilters()\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\"\r\n >Created {{ table?.createdAt | date : \"MMM d, y\" }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\r\n >\r\n <div class=\"muted-text show-hide-table-label\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n />\r\n </div>\r\n <div *ngIf=\"firstValue\">\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{ item?.department_name || item?.roleName || \"-\" }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) ? (getNestedValue(row, col.field) | date:'shortDate') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ getNestedValue(row, col.field) ? (getNestedValue(row, col.field) | date:'shortTime') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) === true || getNestedValue(row, col.field) === 'true') ? 'bg-success' : 'bg-secondary'\">\r\n {{ (getNestedValue(row, col.field) === true || getNestedValue(row, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field))\">\r\n {{ (getNestedValue(row, col.field) || []).length }} items\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field))\">\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n \r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\r\n>\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Manual Logs Modal -->\r\n<div *ngIf=\"showManualLogsModal\" class=\"custom-modal-overlay\">\r\n <div class=\"custom-modal-content manual-logs-modal\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Manual Logs Details</h5>\r\n <button type=\"button\" class=\"btn-close\" (click)=\"closeManualLogsModal()\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous Time</th>\r\n <th>Updated Time</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <!-- Display manually_logs if available - Show ALL entries -->\r\n <ng-container *ngIf=\"currentManualLogsRow?.manually_logs && currentManualLogsRow.manually_logs.length > 0\">\r\n <ng-container *ngFor=\"let item of currentManualLogsRow.manually_logs; let i = index\">\r\n <!-- Clock In Row - Show even if status is null or has data -->\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_in?.previous_state && item.clock_in.previous_state !== 'Absent' && item.clock_in.previous_state !== '-' ? (item.clock_in.previous_state | date:'short') : (item.clock_in.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_in?.time && item.clock_in.time !== 'Absent' && item.clock_in.time !== null && item.clock_in.time !== '_' ? (item.clock_in.time | date:'short') : (item.clock_in.time || '-') }}</td>\r\n <td>{{ item?.clock_in?.status ? transformStatus(item.clock_in.status) : (item.clock_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Clock Out Row - Show even if status is null or has data -->\r\n <tr *ngIf=\"item.clock_out\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_out?.previous_state && item.clock_out.previous_state !== 'Absent' && item.clock_out.previous_state !== '-' ? (item.clock_out.previous_state | date:'short') : (item.clock_out.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_out?.time && item.clock_out.time !== 'Absent' && item.clock_out.time !== null && item.clock_out.time !== '_' ? (item.clock_out.time | date:'short') : (item.clock_out.time || '-') }}</td>\r\n <td>{{ item?.clock_out?.status ? transformStatus(item.clock_out.status) : (item.clock_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Handle breaks -->\r\n <ng-container *ngIf=\"item.breaks && item.breaks.length > 0\">\r\n <ng-container *ngFor=\"let breakItem of item.breaks\">\r\n <!-- Break In -->\r\n <tr *ngIf=\"breakItem?.break_in\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_in?.previous_state && breakItem.break_in.previous_state !== 'Absent' && breakItem.break_in.previous_state !== '-' ? (breakItem.break_in.previous_state | date:'short') : (breakItem.break_in.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.time && breakItem.break_in.time !== 'Absent' && breakItem.break_in.time !== null && breakItem.break_in.time !== '_' ? (breakItem.break_in.time | date:'short') : (breakItem.break_in.time || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.status ? transformStatus(breakItem.break_in.status) : (breakItem.break_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Break Out -->\r\n <tr *ngIf=\"breakItem?.break_out\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_out?.previous_state && breakItem.break_out.previous_state !== 'Absent' && breakItem.break_out.previous_state !== '-' ? (breakItem.break_out.previous_state | date:'short') : (breakItem.break_out.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.time && breakItem.break_out.time !== 'Absent' && breakItem.break_out.time !== null && breakItem.break_out.time !== '_' ? (breakItem.break_out.time | date:'short') : (breakItem.break_out.time || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.status ? transformStatus(breakItem.break_out.status) : (breakItem.break_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Fallback to logs array if manually_logs is empty -->\r\n <ng-container *ngIf=\"(!currentManualLogsRow?.manually_logs || currentManualLogsRow.manually_logs.length === 0) && currentManualLogsRow?.logs\">\r\n <ng-container *ngFor=\"let log of currentManualLogsRow.logs; let i = index\">\r\n <tr>\r\n <td>{{ currentManualLogsRow?.User?.full_name || currentManualLogsRow?.attendance_adjusted_by?.full_name || '-' }}</td>\r\n <td>{{ log?.log_date ? (log.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ currentManualLogsRow?.clock_in_time && currentManualLogsRow.clock_in_time !== 'Absent' ? (currentManualLogsRow.clock_in_time | date:'shortTime') : '-' }}</td>\r\n <td>{{ currentManualLogsRow?.clock_out_time && currentManualLogsRow.clock_out_time !== 'Absent' ? (currentManualLogsRow.clock_out_time | date:'shortTime') : '-' }}</td>\r\n <td>{{ log?.log_status ? transformStatus(log.log_status) : currentManualLogsRow?.attendanceStatus || '-' }}</td>\r\n <td>{{ currentManualLogsRow?.message || log?.remarks || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Show message if no data available -->\r\n <tr *ngIf=\"(!currentManualLogsRow?.manually_logs || currentManualLogsRow.manually_logs.length === 0) && (!currentManualLogsRow?.logs || currentManualLogsRow.logs.length === 0)\">\r\n <td colspan=\"6\" class=\"text-center text-muted\">No manual log details available</td>\r\n </tr>\r\n\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Modal overlay for accordion manual logs tooltip -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"manual-logs-modal-overlay\" (click)=\"hideManualLogsTooltip()\">\r\n <div class=\"manual-logs-modal-content\" (click)=\"$event.stopPropagation()\" (mouseenter)=\"preventManualLogsTooltipHide()\" (mouseleave)=\"hideManualLogsTooltip()\">\r\n <div class=\"modal-header\">\r\n <h5>Manual Logs Details</h5>\r\n <button type=\"button\" class=\"close\" (click)=\"hideManualLogsTooltip()\">&times;</button>\r\n </div>\r\n <div class=\"modal-body\" style=\"max-height: 400px; overflow-y: auto;\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous Time</th>\r\n <th>Updated Time</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <!-- Clock In Row -->\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_in?.previous_state && item.clock_in.previous_state !== 'Absent' && item.clock_in.previous_state !== '-' ? (item.clock_in.previous_state | date:'short') : (item.clock_in.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_in?.time && item.clock_in.time !== 'Absent' && item.clock_in.time !== null && item.clock_in.time !== '_' ? (item.clock_in.time | date:'short') : (item.clock_in.time || '-') }}</td>\r\n <td>{{ item?.clock_in?.status ? transformStatus(item.clock_in.status) : (item.clock_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Clock Out Row -->\r\n <tr *ngIf=\"item.clock_out\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_out?.previous_state && item.clock_out.previous_state !== 'Absent' && item.clock_out.previous_state !== '-' ? (item.clock_out.previous_state | date:'short') : (item.clock_out.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_out?.time && item.clock_out.time !== 'Absent' && item.clock_out.time !== null && item.clock_out.time !== '_' ? (item.clock_out.time | date:'short') : (item.clock_out.time || '-') }}</td>\r\n <td>{{ item?.clock_out?.status ? transformStatus(item.clock_out.status) : (item.clock_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Breaks -->\r\n <ng-container *ngIf=\"item.breaks && item.breaks.length > 0\">\r\n <ng-container *ngFor=\"let breakItem of item.breaks\">\r\n <tr *ngIf=\"breakItem?.break_in\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_in?.previous_state && breakItem.break_in.previous_state !== 'Absent' && breakItem.break_in.previous_state !== '-' ? (breakItem.break_in.previous_state | date:'short') : (breakItem.break_in.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.time && breakItem.break_in.time !== 'Absent' && breakItem.break_in.time !== null && breakItem.break_in.time !== '_' ? (breakItem.break_in.time | date:'short') : (breakItem.break_in.time || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.status ? transformStatus(breakItem.break_in.status) : (breakItem.break_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <tr *ngIf=\"breakItem?.break_out\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_out?.previous_state && breakItem.break_out.previous_state !== 'Absent' && breakItem.break_out.previous_state !== '-' ? (breakItem.break_out.previous_state | date:'short') : (breakItem.break_out.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.time && breakItem.break_out.time !== 'Absent' && breakItem.break_out.time !== null && breakItem.break_out.time !== '_' ? (breakItem.break_out.time | date:'short') : (breakItem.break_out.time || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.status ? transformStatus(breakItem.break_out.status) : (breakItem.break_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #detailModalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative}.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: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: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:80px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;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:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height: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:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.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}.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{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.circle-value{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;background-color:#f0f0f0;border:1px solid #ccc;font-size:12px;font-weight:700;color:#333;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .2s ease}.circle-value:hover{background-color:#d9d9d9;box-shadow:0 2px 4px #0000001a;transform:scale(1.1)}.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:background-color .2s ease;font-size:14px}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{position:absolute;top:0;right:-4px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:40;transition:opacity .2s;background:transparent}th:hover .resize-handle{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .2s ease}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.05)}.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-datepicker-head{background:linear-gradient(135deg,#4361ee,#3a0ca3)!important;color:#fff!important;border-radius:12px 12px 0 0!important;padding:16px 20px!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#fff!important;font-size:16px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff3!important;color:#fff!important;border:none!important;width:32px!important;height:32px!important;border-radius:50%!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#ffffff4d!important;transform:scale(1.05)}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:16px!important;background:#f8f9fa!important;border-top:1px solid #e9ecef!important;border-radius:0 0 12px 12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#4361ee,#3a0ca3)!important;color:#fff!important;border:none!important;box-shadow:0 4px 10px #4361ee4d!important;font-weight:600!important;padding:8px 16px!important;border-radius:8px!important;transition:all .2s ease!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{transform:translateY(-2px)!important;box-shadow:0 6px 14px #4361ee66!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #ced4da!important;font-weight:600!important;padding:8px 16px!important;border-radius:8px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#f1f3f5!important;color:#212529!important;border-color:#adb5bd!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))}.popver_content_progress_bar{visibility:hidden}.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;transition:background-color .2s ease}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item:hover,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item:hover,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item:hover,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item:hover{background-color:#007bff1a}.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}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i3.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: FilterPipe, name: "filter" }, { kind: "pipe", type: PinnedColumnsPipe, name: "pinnedColumns" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i4.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i4.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i4.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i5.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i5.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i6.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i6.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i6.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], animations: [
7429
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeSheetComponent, isStandalone: true, selector: "time-sheet", inputs: { paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", isSingleDay: "isSingleDay", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", enableAccordionShadow: "enableAccordionShadow", enableAccordionSeparators: "enableAccordionSeparators", enableRowShading: "enableRowShading", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBAckgroundColor: "nestedTableHeaderBAckgroundColor", tableView: "tableView", columnThreedotsMunuConfig: "columnThreedotsMunuConfig", timezonePrefs: "timezonePrefs", enableProgressiveLoading: "enableProgressiveLoading", progressiveChunkSize: "progressiveChunkSize", progressiveDelay: "progressiveDelay", enableInfiniteScroll: "enableInfiniteScroll", hasMoreData: "hasMoreData", loadingMore: "loadingMore", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", loadMoreData: "loadMoreData", changeLayout: "changeLayout", filterOptions: "filterOptions", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing", loadMore: "loadMore", emailClicked: "emailClicked", addAttendanceClicked: "addAttendanceClicked", backPayClicked: "backPayClicked", grandTotalClicked: "grandTotalClicked", printClicked: "printClicked", exportClicked: "exportClicked", exportDailyClicked: "exportDailyClicked", deleteClicked: "deleteClicked" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape($event)", "window:resize": "onResize($event)", "document:keydown": "onKeyDown($event)", "document:paste": "onPaste($event)" } }, viewQueries: [{ propertyName: "cellText", first: true, predicate: ["cellText"], descendants: true }, { propertyName: "dataGridContainer", first: true, predicate: ["dataGridContainer"], descendants: true }, { propertyName: "leftPinnedBody", first: true, predicate: ["leftPinnedBody"], descendants: true }, { propertyName: "centerPinnedBody", first: true, predicate: ["centerPinnedBody"], descendants: true }, { propertyName: "rightPinnedBody", first: true, predicate: ["rightPinnedBody"], descendants: true }, { propertyName: "leftPinnedHeader", first: true, predicate: ["leftPinnedHeader"], descendants: true }, { propertyName: "centerPinnedHeader", first: true, predicate: ["centerPinnedHeader"], descendants: true }, { propertyName: "rightPinnedHeader", first: true, predicate: ["rightPinnedHeader"], descendants: true }, { propertyName: "columnsGroupedBox", first: true, predicate: ["columnsGroupedBox"], descendants: true }, { propertyName: "centerFakeScrollbar", first: true, predicate: ["centerFakeScrollbar"], descendants: true }, { propertyName: "centerScroll", first: true, predicate: ["centerScroll"], descendants: true }, { propertyName: "mainScroll", first: true, predicate: ["mainScroll"], descendants: true }, { propertyName: "fakeScroll", first: true, predicate: ["fakeScroll"], descendants: true }, { propertyName: "horizintalFakeScroll", first: true, predicate: ["horizintalFakeScroll"], descendants: true }, { propertyName: "centerScrollableBody", first: true, predicate: ["centerScrollableBody"], descendants: true }, { propertyName: "filterMenueSearchInput", first: true, predicate: ["filterMenueSearchInput"], descendants: true }, { propertyName: "filterMenueTextchInput", first: true, predicate: ["filterMenueTextchInput"], descendants: true }, { propertyName: "headerContainer", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "dataContainer", first: true, predicate: ["dataContainer"], descendants: true }, { propertyName: "leftContainer", first: true, predicate: ["leftContainer"], descendants: true }, { propertyName: "rightContainer", first: true, predicate: ["rightContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n \r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <!-- Email Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"onEmailClick()\"\r\n title=\"Email\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/smsIcon.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Email</span>\r\n</a>\r\n\r\n<!-- Add Attendance Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onAddAttendanceClick()\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/addAttendenceIcon.svg'\"\r\n class=\"svg-icon svg-icon-2 pe-2\"\r\n ></span>\r\n Add Attendance\r\n</a>\r\n\r\n<!-- Back Pay Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onBackPayClick()\"\r\n title=\"Back Pay\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/back pay.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Back pay</span>\r\n</a>\r\n\r\n<!-- Grand Total Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onGrandTotalClick()\"\r\n title=\"Grand Total\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/grandtotal.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Grand totel</span>\r\n</a>\r\n\r\n<!-- Print Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onPrintClick()\"\r\n title=\"Print\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/printIcon.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Print</span>\r\n</a>\r\n\r\n<!-- Export Button (Multi-day) -->\r\n<a\r\n *ngIf=\"!isSingleDay\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onExportClick()\"\r\n title=\"Export\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/general/export.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Export</span>\r\n</a>\r\n\r\n<!-- Export Daily Timesheet (Single-day) -->\r\n<a\r\n *ngIf=\"isSingleDay\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onExportDailyClick()\"\r\n title=\"Export Daily Timesheet\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/general/export.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Export Daily Timesheet</span>\r\n</a>\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n<div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 2px;\r\n top: 2px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n</div>\r\n<!-- <div\r\n class=\"cursor-pointer\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n</div> -->\r\n<div\r\n class=\"cursor-pointer\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a class=\"dropdown-item\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a class=\"dropdown-item\" (click)=\"downloadCsv()\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Download as CSV\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div class=\"d-flex gap-2 align-items-center me-5\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n \r\n\r\n \r\n <div class=\"position-relative d-inline-block ms-5\">\r\n \r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n \r\n <!-- Calendar Icon -->\r\n\r\n <!-- <div class=\"icon-container position-absolute end-0 top-50 translate-middle-y me-2\"\r\n (click)=\"togglePicker(picker)\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/calendar.svg'\"\r\n class=\"data-grid-svg-icon top-icon\"\r\n style=\"cursor: pointer;\"\r\n ></span>\r\n </div> -->\r\n <!-- Calendar Button -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-xs btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Calendar\"\r\n >\r\n <span class=\"bi bi-calendar me-1\"></span>\r\n Calendar\r\n </a>\r\n\r\n <!-- Clear Button -->\r\n <a\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-xs btn btn-outline-danger border border-danger me-2 header-icon\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date\"\r\n >\r\n <span class=\"bi bi-x-circle me-1\"></span>\r\n Clear\r\n </a>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-muted ms-2 me-3\"\r\n style=\"font-size: 14px; font-weight: 500;\"\r\n >\r\n {{ bsRangeValue[0] | date:'shortDate' }} - {{ bsRangeValue[1] | date:'shortDate' }}\r\n </span>\r\n \r\n </div>\r\n\r\n </div>\r\n <div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"65\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n ></div>\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterHeaderScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"openThreeDotsMenu($event, 'group')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"onResizeGroupBox($event)\"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <!-- <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div [style.width.px]=\"30\"></div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'previewRightPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet.length && !loading\"\r\n >\r\n No Record Found\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n <div\r\n *ngIf=\"false\"\r\n class=\"card-view-container p-3\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n >\r\n <div class=\"row g-3\">\r\n <div\r\n *ngFor=\"let row of dataSet; let i = index; trackBy: trackById\"\r\n class=\"col-xl-4 col-lg-6 col-md-6 col-sm-12\"\r\n >\r\n <div class=\"card h-100 shadow-sm attendance-card\" [class.expanded]=\"row.isCardExpanded\">\r\n <!-- Card Header -->\r\n <div class=\"card-header d-flex align-items-center p-3\">\r\n <div class=\"employee-avatar me-3\">\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <img\r\n [width]=\"40\"\r\n [height]=\"40\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"avatar\"\r\n class=\"rounded-circle\"\r\n />\r\n </ng-container>\r\n <ng-template #placeholder>\r\n <div\r\n class=\"avatar-placeholder rounded-circle d-flex align-items-center justify-content-center text-white fw-bold\"\r\n [style.width.px]=\"40\"\r\n [style.height.px]=\"40\"\r\n [style.fontSize.px]=\"16\"\r\n [style.backgroundColor]=\"getAvatarColor(row?.User?.full_name || row?.full_name || row?.name)\"\r\n >\r\n {{ getInitialss(row?.User?.full_name || row?.full_name || row?.name) }}\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <h6 class=\"mb-1 fw-bold\">{{ row?.User?.full_name || row?.full_name || row?.name || 'N/A' }}</h6>\r\n <small class=\"text-muted\">{{ row?.attendanceDate | date:'mediumDate' }}</small>\r\n </div>\r\n <div class=\"card-actions\">\r\n <button\r\n class=\"btn btn-sm btn-outline-primary\"\r\n (click)=\"row.isCardExpanded = !row.isCardExpanded\"\r\n [title]=\"row.isCardExpanded ? 'Collapse' : 'Expand'\"\r\n >\r\n <i class=\"bi\" [class]=\"row.isCardExpanded ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Card Body -->\r\n <div class=\"card-body p-3\">\r\n <!-- Basic Attendance Info -->\r\n <div class=\"row g-2 mb-3\">\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock In</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_in_time ? (row.clock_in_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock Out</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_out_time ? (row.clock_out_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Total Hours</small>\r\n <span class=\"fw-semibold\">{{ calculateTotalHours(row) }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Status</small>\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(row?.attendanceStatus)\">{{ row?.attendanceStatus || 'Unknown' }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Expandable Details -->\r\n <div class=\"card-details\" *ngIf=\"row.isCardExpanded\">\r\n <hr class=\"my-3\">\r\n\r\n <!-- All Column Data Section -->\r\n <div class=\"all-columns-section mb-3\">\r\n <h6 class=\"section-title mb-3\">\r\n <i class=\"bi bi-table me-2\"></i>All Details\r\n </h6>\r\n <div class=\"row g-2\">\r\n <ng-container *ngFor=\"let col of centerColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of leftPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of rightPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Breaks Section -->\r\n <div class=\"breaks-section mb-3\" *ngIf=\"row?.breaks?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-clock-history me-2\"></i>Breaks\r\n </h6>\r\n <div class=\"breaks-list\">\r\n <div\r\n *ngFor=\"let breakItem of row.breaks; let bIndex = index\"\r\n class=\"break-item p-2 border rounded mb-2\"\r\n [title]=\"getBreakTooltip(breakItem)\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ breakItem?.break_type?.data_value_name || ('Break ' + (bIndex + 1)) }}</small>\r\n <div class=\"text-muted small\">\r\n {{ breakItem?.break_in_time ? (breakItem.break_in_time | date:'shortTime') : '--:--' }} -\r\n {{ breakItem?.break_out_time ? (breakItem.break_out_time | date:'shortTime') : '--:--' }}\r\n </div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-info\">{{ breakItem?.break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Breaks Section -->\r\n <div class=\"short-breaks-section mb-3\" *ngIf=\"row?.short_breaks\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pause-circle me-2\"></i>Short Breaks\r\n </h6>\r\n <div class=\"short-break-item p-2 border rounded\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ row.short_breaks?.short_break_name || 'Quick Break' }}</small>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-warning\">{{ row.short_breaks?.short_break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Leave Section -->\r\n <div class=\"short-leave-section mb-3\" *ngIf=\"row?.short_leave?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-calendar-x me-2\"></i>Short Leave\r\n </h6>\r\n <div class=\"short-leave-list\">\r\n <div\r\n *ngFor=\"let leave of row.short_leave\"\r\n class=\"leave-item p-2 border rounded mb-2\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ leave?.leave_type || 'Leave' }}</small>\r\n <div class=\"text-muted small\">{{ leave?.minutes || 0 }} minutes</div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-danger\">Leave</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Manual Logs Section -->\r\n <div class=\"manual-logs-section mb-3\" *ngIf=\"row?.manually_logs?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pencil-square me-2\"></i>Manual Logs\r\n </h6>\r\n <button\r\n class=\"btn btn-sm btn-outline-info\"\r\n (click)=\"openManualLogsModal($event, row)\"\r\n title=\"View Manual Logs Details\"\r\n >\r\n <i class=\"bi bi-eye me-1\"></i>View Details\r\n </button>\r\n </div>\r\n\r\n <!-- Additional Details -->\r\n <div class=\"additional-details\">\r\n <div class=\"row g-2\">\r\n <div class=\"col-6\" *ngIf=\"row?.overtime_hours\">\r\n <small class=\"text-muted d-block\">Overtime</small>\r\n <span class=\"fw-semibold\">{{ row.overtime_hours }}h</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.late_minutes\">\r\n <small class=\"text-muted d-block\">Late Minutes</small>\r\n <span class=\"fw-semibold\">{{ row.late_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.early_departure_minutes\">\r\n <small class=\"text-muted d-block\">Early Departure</small>\r\n <span class=\"fw-semibold\">{{ row.early_departure_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.message\">\r\n <small class=\"text-muted d-block\">Remarks</small>\r\n <span class=\"fw-semibold text-truncate d-block\" [title]=\"row.message\">{{ row.message }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table View -->\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length) + (hasMoreData ? 1000 : 0)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onHorizintalFakeScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, child)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"onResizeColumn($event, child)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div class=\"group-column-wrapper\">\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"onResizeColumn($event, col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"65\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"65\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n </div>\r\n <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4 border-right\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (click)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on me-2 text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <div class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeavePopover($event, d)\"\r\n (mouseleave)=\"hideShortLeavePopover()\">\r\n <span class=\"d-block\"\r\n [style.min-width.%]=\"(d.short_leave && d.short_leave.length > 0) ? d.short_leave[0].short_leave_time_percentage : 0\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ (d.short_leave && d.short_leave.length > 0) ? d.short_leave[0].short_leave_time_percentage : 0 }}%</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [ngClass]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [ngClass]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { \r\n break_duration: 0, \r\n break_type: { data_value_name: 'No Break' }, \r\n breakInstatus: 'None',\r\n break_in_time: null,\r\n break_out_time: null\r\n })\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n 0m\r\n </div>\r\n</ng-template>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeavePopover($event, d)\"\r\n (mouseleave)=\"hideShortLeavePopover()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <!-- <ng-template #noShortLeaveDetail>\r\n <div class=\"circle-value\">0%</div>\r\n </ng-template> -->\r\n </div>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (click)=\"showManualLogsTooltip($event, row, d)\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"rowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (click)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on me-2 text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveLeft\">\r\n <div class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\">\r\n <span class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <!-- <ng-template #noShortLeaveLeft>\r\n <div class=\"circle-value\">0%</div>\r\n </ng-template> -->\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col.type === 'date'\r\n ? (getNestedValue(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <div class=\"d-flex justify-content-center align-items-center flex-wrap gap-1\">\r\n <span *ngFor=\"let breakItem of getNestedValue(row, 'breaks'); trackBy: trackById\" class=\"popover__wrapper\" (mouseenter)=\"showBreakTooltip($event, breakItem)\" (mouseleave)=\"hideBreakTooltip()\">\r\n <span class=\"circle-value badge-outline break-on text-center\" [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div class=\"circle-value text-muted text-center\" (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\" (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [style.backgroundColor]=\"getBreakColor(row.short_breaks.type)\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div class=\"circle-value text-center\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\" (mouseleave)=\"hideShortBreakTooltip()\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\" (mouseenter)=\"showShortLeavePopover($event, row)\" (mouseleave)=\"hideShortLeavePopover()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"(row.short_leave && row.short_leave.length > 0) ? row.short_leave[0].short_leave_time_percentage : 0\" style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ (row.short_leave && row.short_leave.length > 0) ? row.short_leave[0].short_leave_time_percentage : 0 }}%</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [ngClass]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [ngClass]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? (getNestedValue(row, col.field) | date: dateFormat)\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\" (mouseleave)=\"hideManualLogsTooltip()\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon -->\r\n <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> In: {{ currentBreakTooltip.break_in_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> Out: {{ currentBreakTooltip.break_out_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentBreakTooltip.break_duration }} min</div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> Start: {{ currentShortBreakTooltip.start_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> End: {{ currentShortBreakTooltip.end_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentShortBreakTooltip.short_break_duration }} min</div>\r\n </div>\r\n</div>\r\n\r\n\r\n<!-- Short Leave Popover (Detail Rows) -->\r\n<div\r\n *ngIf=\"isShortLeavePopoverVisible\"\r\n class=\"popver_content_progress_bar\"\r\n [style.position]=\"'fixed'\"\r\n [style.top.px]=\"shortLeaveTooltipPosition.y + 10\"\r\n [style.left.px]=\"shortLeaveTooltipPosition.x\"\r\n style=\"z-index: 1000; background: white; border: 1px solid #ddd; border-radius: 6px; padding: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); width: 250px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area\">\r\n <div class=\"table-responsive iis-scrollbar table-container\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-3\" style=\"font-size: xx-small;\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 20%;\">Leave Type</th>\r\n <th class=\"center\">Start</th>\r\n <th class=\"center\">End</th>\r\n <th class=\"center\">Duration</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let leave of currentShortLeaveData\">\r\n <td class=\"center\">{{ leave.leave_type || 'Short Leave' }}</td>\r\n <td class=\"center\">{{ leave.star_time || leave.start_time || '\u2013' }}</td>\r\n <td class=\"center\">{{ leave.end_time || '\u2013' }}</td>\r\n <td class=\"center\">{{ leave.hours }}H {{ leave.minutes % 60 }}M</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" [class.visually-hidden]=\"isMenueHidden\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col.query.first_value\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container *ngIf=\"col.query?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n />\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n</div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation();\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save Preset\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div class=\"\">\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <span\r\n *ngIf=\"!tableFilterViewId\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"clearAllFilters()\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\"\r\n >Created {{ table?.createdAt | date : \"MMM d, y\" }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\r\n >\r\n <div class=\"muted-text show-hide-table-label\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n />\r\n </div>\r\n <div *ngIf=\"firstValue\">\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{ item?.department_name || item?.roleName || \"-\" }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | date:'shortDate') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | date:'shortTime') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'bg-success' : 'bg-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [ngClass]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\r\n>\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Manual Logs Modal -->\r\n<div *ngIf=\"showManualLogsModal\" class=\"custom-modal-overlay\">\r\n <div class=\"custom-modal-content manual-logs-modal\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Manual Logs Details</h5>\r\n <button type=\"button\" class=\"btn-close\" (click)=\"closeManualLogsModal()\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous Time</th>\r\n <th>Updated Time</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <!-- Display manually_logs if available - Show ALL entries -->\r\n <ng-container *ngIf=\"currentManualLogsRow?.manually_logs && currentManualLogsRow.manually_logs.length > 0\">\r\n <ng-container *ngFor=\"let item of currentManualLogsRow.manually_logs; let i = index\">\r\n <!-- Clock In Row - Show even if status is null or has data -->\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_in?.previous_state && item.clock_in.previous_state !== 'Absent' && item.clock_in.previous_state !== '-' ? (item.clock_in.previous_state | date:'short') : (item.clock_in.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_in?.time && item.clock_in.time !== 'Absent' && item.clock_in.time !== null && item.clock_in.time !== '_' ? (item.clock_in.time | date:'short') : (item.clock_in.time || '-') }}</td>\r\n <td>{{ item?.clock_in?.status ? transformStatus(item.clock_in.status) : (item.clock_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Clock Out Row - Show even if status is null or has data -->\r\n <tr *ngIf=\"item.clock_out\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_out?.previous_state && item.clock_out.previous_state !== 'Absent' && item.clock_out.previous_state !== '-' ? (item.clock_out.previous_state | date:'short') : (item.clock_out.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_out?.time && item.clock_out.time !== 'Absent' && item.clock_out.time !== null && item.clock_out.time !== '_' ? (item.clock_out.time | date:'short') : (item.clock_out.time || '-') }}</td>\r\n <td>{{ item?.clock_out?.status ? transformStatus(item.clock_out.status) : (item.clock_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Handle breaks -->\r\n <ng-container *ngIf=\"item.breaks && item.breaks.length > 0\">\r\n <ng-container *ngFor=\"let breakItem of item.breaks\">\r\n <!-- Break In -->\r\n <tr *ngIf=\"breakItem?.break_in\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_in?.previous_state && breakItem.break_in.previous_state !== 'Absent' && breakItem.break_in.previous_state !== '-' ? (breakItem.break_in.previous_state | date:'short') : (breakItem.break_in.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.time && breakItem.break_in.time !== 'Absent' && breakItem.break_in.time !== null && breakItem.break_in.time !== '_' ? (breakItem.break_in.time | date:'short') : (breakItem.break_in.time || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.status ? transformStatus(breakItem.break_in.status) : (breakItem.break_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Break Out -->\r\n <tr *ngIf=\"breakItem?.break_out\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_out?.previous_state && breakItem.break_out.previous_state !== 'Absent' && breakItem.break_out.previous_state !== '-' ? (breakItem.break_out.previous_state | date:'short') : (breakItem.break_out.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.time && breakItem.break_out.time !== 'Absent' && breakItem.break_out.time !== null && breakItem.break_out.time !== '_' ? (breakItem.break_out.time | date:'short') : (breakItem.break_out.time || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.status ? transformStatus(breakItem.break_out.status) : (breakItem.break_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Fallback to logs array if manually_logs is empty -->\r\n <ng-container *ngIf=\"(!currentManualLogsRow?.manually_logs || currentManualLogsRow.manually_logs.length === 0) && currentManualLogsRow?.logs\">\r\n <ng-container *ngFor=\"let log of currentManualLogsRow.logs; let i = index\">\r\n <tr>\r\n <td>{{ currentManualLogsRow?.User?.full_name || currentManualLogsRow?.attendance_adjusted_by?.full_name || '-' }}</td>\r\n <td>{{ log?.log_date ? (log.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ currentManualLogsRow?.clock_in_time && currentManualLogsRow.clock_in_time !== 'Absent' ? (currentManualLogsRow.clock_in_time | date:'shortTime') : '-' }}</td>\r\n <td>{{ currentManualLogsRow?.clock_out_time && currentManualLogsRow.clock_out_time !== 'Absent' ? (currentManualLogsRow.clock_out_time | date:'shortTime') : '-' }}</td>\r\n <td>{{ log?.log_status ? transformStatus(log.log_status) : currentManualLogsRow?.attendanceStatus || '-' }}</td>\r\n <td>{{ currentManualLogsRow?.message || log?.remarks || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Show message if no data available -->\r\n <tr *ngIf=\"(!currentManualLogsRow?.manually_logs || currentManualLogsRow.manually_logs.length === 0) && (!currentManualLogsRow?.logs || currentManualLogsRow.logs.length === 0)\">\r\n <td colspan=\"6\" class=\"text-center text-muted\">No manual log details available</td>\r\n </tr>\r\n\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Modal overlay for accordion manual logs tooltip -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"manual-logs-modal-overlay\" (click)=\"hideManualLogsTooltip()\">\r\n <div class=\"manual-logs-modal-content\" (click)=\"$event.stopPropagation()\" (mouseenter)=\"preventManualLogsTooltipHide()\" (mouseleave)=\"hideManualLogsTooltip()\">\r\n <div class=\"modal-header\">\r\n <h5>Manual Logs Details</h5>\r\n <button type=\"button\" class=\"close\" (click)=\"hideManualLogsTooltip()\">&times;</button>\r\n </div>\r\n <div class=\"modal-body\" style=\"max-height: 400px; overflow-y: auto;\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous Time</th>\r\n <th>Updated Time</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <!-- Clock In Row -->\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_in?.previous_state && item.clock_in.previous_state !== 'Absent' && item.clock_in.previous_state !== '-' ? (item.clock_in.previous_state | date:'short') : (item.clock_in.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_in?.time && item.clock_in.time !== 'Absent' && item.clock_in.time !== null && item.clock_in.time !== '_' ? (item.clock_in.time | date:'short') : (item.clock_in.time || '-') }}</td>\r\n <td>{{ item?.clock_in?.status ? transformStatus(item.clock_in.status) : (item.clock_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Clock Out Row -->\r\n <tr *ngIf=\"item.clock_out\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_out?.previous_state && item.clock_out.previous_state !== 'Absent' && item.clock_out.previous_state !== '-' ? (item.clock_out.previous_state | date:'short') : (item.clock_out.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_out?.time && item.clock_out.time !== 'Absent' && item.clock_out.time !== null && item.clock_out.time !== '_' ? (item.clock_out.time | date:'short') : (item.clock_out.time || '-') }}</td>\r\n <td>{{ item?.clock_out?.status ? transformStatus(item.clock_out.status) : (item.clock_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Breaks -->\r\n <ng-container *ngIf=\"item.breaks && item.breaks.length > 0\">\r\n <ng-container *ngFor=\"let breakItem of item.breaks\">\r\n <tr *ngIf=\"breakItem?.break_in\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_in?.previous_state && breakItem.break_in.previous_state !== 'Absent' && breakItem.break_in.previous_state !== '-' ? (breakItem.break_in.previous_state | date:'short') : (breakItem.break_in.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.time && breakItem.break_in.time !== 'Absent' && breakItem.break_in.time !== null && breakItem.break_in.time !== '_' ? (breakItem.break_in.time | date:'short') : (breakItem.break_in.time || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.status ? transformStatus(breakItem.break_in.status) : (breakItem.break_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <tr *ngIf=\"breakItem?.break_out\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_out?.previous_state && breakItem.break_out.previous_state !== 'Absent' && breakItem.break_out.previous_state !== '-' ? (breakItem.break_out.previous_state | date:'short') : (breakItem.break_out.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.time && breakItem.break_out.time !== 'Absent' && breakItem.break_out.time !== null && breakItem.break_out.time !== '_' ? (breakItem.break_out.time | date:'short') : (breakItem.break_out.time || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.status ? transformStatus(breakItem.break_out.status) : (breakItem.break_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #detailModalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative}.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: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: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:80px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;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:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height: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:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.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}.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{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.circle-value{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;background-color:#f0f0f0;border:1px solid #ccc;font-size:12px;font-weight:700;color:#333;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .2s ease}.circle-value:hover{background-color:#d9d9d9;box-shadow:0 2px 4px #0000001a;transform:scale(1.1)}.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:background-color .2s ease;font-size:14px}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{position:absolute;top:0;right:-4px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:40;transition:opacity .2s;background:transparent}th:hover .resize-handle{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .2s ease}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.05)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;height:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{background:#fff!important;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))}.popver_content_progress_bar{visibility:hidden}.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;transition:background-color .2s ease}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item:hover,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item:hover,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item:hover,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item:hover{background-color:#007bff1a}.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}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i3.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: FilterPipe, name: "filter" }, { kind: "pipe", type: PinnedColumnsPipe, name: "pinnedColumns" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i4.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i4.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i4.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i4.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i4.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i4.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i5.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i5.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i6.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i6.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i6.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], animations: [
7567
7430
  trigger('accordionToggle', [
7568
7431
  state('collapsed', style({ height: '0px', overflow: 'hidden' })),
7569
7432
  state('expanded', style({ height: '*', overflow: 'visible' })),
@@ -7611,7 +7474,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7611
7474
  transition('void => *', animate('300ms ease-out')),
7612
7475
  transition('* => void', animate('300ms ease-in')),
7613
7476
  ])
7614
- ], template: "<div class=\"position-relative h-100\" [attr.data-theme]=\"currentTheme\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n \r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- View Mode Buttons -->\r\n <div class=\"btn-group me-2\" role=\"group\" aria-label=\"View modes\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'standard'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'standard'\"\r\n (click)=\"toggleViewMode('standard')\"\r\n title=\"Standard View\"\r\n >\r\n <i class=\"bi bi-grid\"></i>\r\n </button>\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'compact'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'compact'\"\r\n (click)=\"toggleViewMode('compact')\"\r\n title=\"Compact View\"\r\n >\r\n <i class=\"bi bi-list\"></i>\r\n </button> -->\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'detailed'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'detailed'\"\r\n (click)=\"toggleViewMode('detailed')\"\r\n title=\"Detailed View\"\r\n >\r\n <i class=\"bi bi-table\"></i>\r\n </button> -->\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'timeline'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'timeline'\"\r\n (click)=\"toggleViewMode('timeline')\"\r\n title=\"Timeline View\"\r\n >\r\n <i class=\"bi bi-clock-history\"></i>\r\n </button> -->\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'calendar'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'calendar'\"\r\n (click)=\"toggleViewMode('calendar')\"\r\n title=\"Calendar View\"\r\n >\r\n <i class=\"bi bi-calendar\"></i>\r\n </button> -->\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'card'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'card'\"\r\n (click)=\"toggleViewMode('card')\"\r\n title=\"Card View\"\r\n >\r\n <i class=\"bi bi-card-text\"></i>\r\n </button>\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-sm\"\r\n [class.btn-primary]=\"viewMode === 'heatmap'\"\r\n [class.btn-outline-primary]=\"viewMode !== 'heatmap'\"\r\n (click)=\"toggleViewMode('heatmap')\"\r\n title=\"Heatmap View\"\r\n >\r\n <i class=\"bi bi-fire\"></i>\r\n </button> -->\r\n </div>\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <!-- Theme Selector Button -->\r\n <div class=\"position-relative\">\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"toggleThemeSelector()\"\r\n title=\"Change Theme\"\r\n >\r\n <i class=\"bi bi-palette\"></i>\r\n </a>\r\n\r\n <!-- Color Picker -->\r\n <div\r\n *ngIf=\"showThemeSelector\"\r\n class=\"position-absolute mt-1 shadow rounded-3 bg-white border\"\r\n style=\"z-index: 1050; right: 0; min-width: 200px;\"\r\n >\r\n <div class=\"p-2\">\r\n <div class=\"fw-semibold mb-2 px-2\">Select Theme Color</div>\r\n <div class=\"d-flex flex-column gap-2\">\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm\"\r\n [class.btn-outline-primary]=\"currentTheme === 'white'\"\r\n (click)=\"selectTheme('white')\"\r\n style=\"flex: 1;\"\r\n >\r\n <i class=\"bi bi-sun me-2\"></i>Light\r\n </button>\r\n <button\r\n class=\"btn btn-sm\"\r\n [class.btn-outline-primary]=\"currentTheme === 'blue'\"\r\n (click)=\"selectTheme('blue')\"\r\n style=\"flex: 1;\"\r\n >\r\n <i class=\"bi bi-droplet me-2\"></i>Blue\r\n </button>\r\n </div>\r\n <div class=\"d-flex align-items-center gap-2\">\r\n <label class=\"form-label mb-0\" style=\"font-size: 12px;\">Custom:</label>\r\n <input\r\n type=\"color\"\r\n class=\"form-control form-control-sm\"\r\n [(ngModel)]=\"customThemeColor\"\r\n (change)=\"applyCustomTheme()\"\r\n style=\"width: 40px; height: 30px; padding: 0; border: none; cursor: pointer;\"\r\n />\r\n <span class=\"text-muted\" style=\"font-size: 11px;\">{{ customThemeColor }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Email Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"onEmailClick()\"\r\n title=\"Email\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/smsIcon.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Email</span>\r\n</a>\r\n\r\n<!-- Add Attendance Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onAddAttendanceClick()\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/addAttendenceIcon.svg'\"\r\n class=\"svg-icon svg-icon-2 pe-2\"\r\n ></span>\r\n Add Attendance\r\n</a>\r\n\r\n<!-- Back Pay Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onBackPayClick()\"\r\n title=\"Back Pay\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/back pay.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Back pay</span>\r\n</a>\r\n\r\n<!-- Grand Total Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onGrandTotalClick()\"\r\n title=\"Grand Total\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/grandtotal.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Grand totel</span>\r\n</a>\r\n\r\n<!-- Print Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onPrintClick()\"\r\n title=\"Print\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/printIcon.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Print</span>\r\n</a>\r\n\r\n<!-- Export Button (Multi-day) -->\r\n<a\r\n *ngIf=\"!isSingleDay\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onExportClick()\"\r\n title=\"Export\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/general/export.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Export</span>\r\n</a>\r\n\r\n<!-- Export Daily Timesheet (Single-day) -->\r\n<a\r\n *ngIf=\"isSingleDay\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onExportDailyClick()\"\r\n title=\"Export Daily Timesheet\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/general/export.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Export Daily Timesheet</span>\r\n</a>\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n<div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 2px;\r\n top: 2px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n</div>\r\n<!-- <div\r\n class=\"cursor-pointer\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n</div> -->\r\n<div\r\n class=\"cursor-pointer\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a class=\"dropdown-item\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a class=\"dropdown-item\" (click)=\"downloadCsv()\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Download as CSV\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div class=\"d-flex gap-2 align-items-center me-5\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n \r\n\r\n \r\n <div class=\"position-relative d-inline-block ms-5\">\r\n \r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n \r\n <!-- Calendar Icon -->\r\n\r\n <!-- <div class=\"icon-container position-absolute end-0 top-50 translate-middle-y me-2\"\r\n (click)=\"togglePicker(picker)\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/calendar.svg'\"\r\n class=\"data-grid-svg-icon top-icon\"\r\n style=\"cursor: pointer;\"\r\n ></span>\r\n </div> -->\r\n <div class=\"icon-container position-absolute end-0 top-50 translate-middle-y d-flex align-items-center\">\r\n <i\r\n class=\"bi bi-calendar me-1\"\r\n style=\"cursor: pointer;\"\r\n (click)=\"togglePicker(picker)\"\r\n ></i>\r\n <!-- Clear Icon -->\r\n <i\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"bi bi-x-circle text-danger\"\r\n style=\"cursor: pointer;\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date\"\r\n ></i>\r\n </div>\r\n \r\n </div>\r\n\r\n </div>\r\n <div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"65\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n ></div>\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterHeaderScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"openThreeDotsMenu($event, 'group')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"onResizeGroupBox($event)\"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <!-- <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div [style.width.px]=\"30\"></div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'previewRightPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet.length && !loading\"\r\n >\r\n No Record Found\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n <div\r\n *ngIf=\"viewMode === 'card'\"\r\n class=\"card-view-container p-3\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n >\r\n <div class=\"row g-3\">\r\n <div\r\n *ngFor=\"let row of dataSet; let i = index; trackBy: trackById\"\r\n class=\"col-xl-4 col-lg-6 col-md-6 col-sm-12\"\r\n >\r\n <div class=\"card h-100 shadow-sm attendance-card\" [class.expanded]=\"row.isCardExpanded\">\r\n <!-- Card Header -->\r\n <div class=\"card-header d-flex align-items-center p-3\">\r\n <div class=\"employee-avatar me-3\">\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <img\r\n [width]=\"40\"\r\n [height]=\"40\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"avatar\"\r\n class=\"rounded-circle\"\r\n />\r\n </ng-container>\r\n <ng-template #placeholder>\r\n <div\r\n class=\"avatar-placeholder rounded-circle d-flex align-items-center justify-content-center text-white fw-bold\"\r\n [style.width.px]=\"40\"\r\n [style.height.px]=\"40\"\r\n [style.fontSize.px]=\"16\"\r\n [style.backgroundColor]=\"getAvatarColor(row?.User?.full_name || row?.full_name || row?.name)\"\r\n >\r\n {{ getInitialss(row?.User?.full_name || row?.full_name || row?.name) }}\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <h6 class=\"mb-1 fw-bold\">{{ row?.User?.full_name || row?.full_name || row?.name || 'N/A' }}</h6>\r\n <small class=\"text-muted\">{{ row?.attendanceDate | date:'mediumDate' }}</small>\r\n </div>\r\n <div class=\"card-actions\">\r\n <button\r\n class=\"btn btn-sm btn-outline-primary\"\r\n (click)=\"row.isCardExpanded = !row.isCardExpanded\"\r\n [title]=\"row.isCardExpanded ? 'Collapse' : 'Expand'\"\r\n >\r\n <i class=\"bi\" [class]=\"row.isCardExpanded ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Card Body -->\r\n <div class=\"card-body p-3\">\r\n <!-- Basic Attendance Info -->\r\n <div class=\"row g-2 mb-3\">\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock In</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_in_time ? (row.clock_in_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock Out</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_out_time ? (row.clock_out_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Total Hours</small>\r\n <span class=\"fw-semibold\">{{ calculateTotalHours(row) }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Status</small>\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(row?.attendanceStatus)\">{{ row?.attendanceStatus || 'Unknown' }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Expandable Details -->\r\n <div class=\"card-details\" *ngIf=\"row.isCardExpanded\">\r\n <hr class=\"my-3\">\r\n\r\n <!-- All Column Data Section -->\r\n <div class=\"all-columns-section mb-3\">\r\n <h6 class=\"section-title mb-3\">\r\n <i class=\"bi bi-table me-2\"></i>All Details\r\n </h6>\r\n <div class=\"row g-2\">\r\n <ng-container *ngFor=\"let col of centerColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of leftPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of rightPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Breaks Section -->\r\n <div class=\"breaks-section mb-3\" *ngIf=\"row?.breaks?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-clock-history me-2\"></i>Breaks\r\n </h6>\r\n <div class=\"breaks-list\">\r\n <div\r\n *ngFor=\"let breakItem of row.breaks; let bIndex = index\"\r\n class=\"break-item p-2 border rounded mb-2\"\r\n [title]=\"getBreakTooltip(breakItem)\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ breakItem?.break_type?.data_value_name || ('Break ' + (bIndex + 1)) }}</small>\r\n <div class=\"text-muted small\">\r\n {{ breakItem?.break_in_time ? (breakItem.break_in_time | date:'shortTime') : '--:--' }} -\r\n {{ breakItem?.break_out_time ? (breakItem.break_out_time | date:'shortTime') : '--:--' }}\r\n </div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-info\">{{ breakItem?.break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Breaks Section -->\r\n <div class=\"short-breaks-section mb-3\" *ngIf=\"row?.short_breaks\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pause-circle me-2\"></i>Short Breaks\r\n </h6>\r\n <div class=\"short-break-item p-2 border rounded\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ row.short_breaks?.short_break_name || 'Quick Break' }}</small>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-warning\">{{ row.short_breaks?.short_break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Leave Section -->\r\n <div class=\"short-leave-section mb-3\" *ngIf=\"row?.short_leave?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-calendar-x me-2\"></i>Short Leave\r\n </h6>\r\n <div class=\"short-leave-list\">\r\n <div\r\n *ngFor=\"let leave of row.short_leave\"\r\n class=\"leave-item p-2 border rounded mb-2\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ leave?.leave_type || 'Leave' }}</small>\r\n <div class=\"text-muted small\">{{ leave?.minutes || 0 }} minutes</div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-danger\">Leave</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Manual Logs Section -->\r\n <div class=\"manual-logs-section mb-3\" *ngIf=\"row?.manually_logs?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pencil-square me-2\"></i>Manual Logs\r\n </h6>\r\n <button\r\n class=\"btn btn-sm btn-outline-info\"\r\n (click)=\"openManualLogsModal($event, row)\"\r\n title=\"View Manual Logs Details\"\r\n >\r\n <i class=\"bi bi-eye me-1\"></i>View Details\r\n </button>\r\n </div>\r\n\r\n <!-- Additional Details -->\r\n <div class=\"additional-details\">\r\n <div class=\"row g-2\">\r\n <div class=\"col-6\" *ngIf=\"row?.overtime_hours\">\r\n <small class=\"text-muted d-block\">Overtime</small>\r\n <span class=\"fw-semibold\">{{ row.overtime_hours }}h</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.late_minutes\">\r\n <small class=\"text-muted d-block\">Late Minutes</small>\r\n <span class=\"fw-semibold\">{{ row.late_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.early_departure_minutes\">\r\n <small class=\"text-muted d-block\">Early Departure</small>\r\n <span class=\"fw-semibold\">{{ row.early_departure_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.message\">\r\n <small class=\"text-muted d-block\">Remarks</small>\r\n <span class=\"fw-semibold text-truncate d-block\" [title]=\"row.message\">{{ row.message }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table View -->\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n *ngIf=\"dataSet.length && viewMode !== 'card'\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length) + (hasMoreData ? 1000 : 0)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onHorizintalFakeScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, child)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"onResizeColumn($event, child)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div class=\"group-column-wrapper\">\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"onResizeColumn($event, col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"65\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"65\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n </div>\r\n <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4 border-right\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (click)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on me-2 text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <div class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeavePopover($event, d)\"\r\n (mouseleave)=\"hideShortLeavePopover()\">\r\n <span class=\"d-block\"\r\n [style.min-width.%]=\"(d.short_leave && d.short_leave.length > 0) ? d.short_leave[0].short_leave_time_percentage : 0\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ (d.short_leave && d.short_leave.length > 0) ? d.short_leave[0].short_leave_time_percentage : 0 }}%</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: inline-flex; gap: 4px; align-items: center; height: 100%; justify-content: center; text-align: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { \r\n break_duration: 0, \r\n break_type: { data_value_name: 'No Break' }, \r\n breakInstatus: 'None',\r\n break_in_time: null,\r\n break_out_time: null\r\n })\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n 0m\r\n </div>\r\n</ng-template>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeavePopover($event, d)\"\r\n (mouseleave)=\"hideShortLeavePopover()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <!-- <ng-template #noShortLeaveDetail>\r\n <div class=\"circle-value\">0%</div>\r\n </ng-template> -->\r\n </div>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (click)=\"showManualLogsTooltip($event, row, d)\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"rowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (click)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on me-2 text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveLeft\">\r\n <div class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\">\r\n <span class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <!-- <ng-template #noShortLeaveLeft>\r\n <div class=\"circle-value\">0%</div>\r\n </ng-template> -->\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col.type === 'date'\r\n ? (getNestedValue(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <div class=\"d-flex justify-content-center align-items-center flex-wrap gap-1\">\r\n <span *ngFor=\"let breakItem of getNestedValue(row, 'breaks'); trackBy: trackById\" class=\"popover__wrapper\" (mouseenter)=\"showBreakTooltip($event, breakItem)\" (mouseleave)=\"hideBreakTooltip()\">\r\n <span class=\"circle-value badge-outline break-on text-center\" [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div class=\"circle-value text-muted text-center\" (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\" (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [style.backgroundColor]=\"getBreakColor(row.short_breaks.type)\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div class=\"circle-value text-center\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\" (mouseleave)=\"hideShortBreakTooltip()\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\" (mouseenter)=\"showShortLeavePopover($event, row)\" (mouseleave)=\"hideShortLeavePopover()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"(row.short_leave && row.short_leave.length > 0) ? row.short_leave[0].short_leave_time_percentage : 0\" style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ (row.short_leave && row.short_leave.length > 0) ? row.short_leave[0].short_leave_time_percentage : 0 }}%</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? (getNestedValue(row, col.field) | date: dateFormat)\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\" (mouseleave)=\"hideManualLogsTooltip()\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon -->\r\n <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> In: {{ currentBreakTooltip.break_in_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> Out: {{ currentBreakTooltip.break_out_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentBreakTooltip.break_duration }} min</div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> Start: {{ currentShortBreakTooltip.start_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> End: {{ currentShortBreakTooltip.end_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentShortBreakTooltip.short_break_duration }} min</div>\r\n </div>\r\n</div>\r\n\r\n\r\n<!-- Short Leave Popover (Detail Rows) -->\r\n<div\r\n *ngIf=\"isShortLeavePopoverVisible\"\r\n class=\"popver_content_progress_bar\"\r\n [style.position]=\"'fixed'\"\r\n [style.top.px]=\"shortLeaveTooltipPosition.y + 10\"\r\n [style.left.px]=\"shortLeaveTooltipPosition.x\"\r\n style=\"z-index: 1000; background: white; border: 1px solid #ddd; border-radius: 6px; padding: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); width: 250px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area\">\r\n <div class=\"table-responsive iis-scrollbar table-container\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-3\" style=\"font-size: xx-small;\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 20%;\">Leave Type</th>\r\n <th class=\"center\">Start</th>\r\n <th class=\"center\">End</th>\r\n <th class=\"center\">Duration</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let leave of currentShortLeaveData\">\r\n <td class=\"center\">{{ leave.leave_type || 'Short Leave' }}</td>\r\n <td class=\"center\">{{ leave.star_time || leave.start_time || '\u2013' }}</td>\r\n <td class=\"center\">{{ leave.end_time || '\u2013' }}</td>\r\n <td class=\"center\">{{ leave.hours }}H {{ leave.minutes % 60 }}M</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" [class.visually-hidden]=\"isMenueHidden\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col.query.first_value\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container *ngIf=\"col.query?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n />\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n</div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.firt_value\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.firt_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation();\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save Preset\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div class=\"\">\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <span\r\n *ngIf=\"!tableFilterViewId\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"clearAllFilters()\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\"\r\n >Created {{ table?.createdAt | date : \"MMM d, y\" }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\r\n >\r\n <div class=\"muted-text show-hide-table-label\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n />\r\n </div>\r\n <div *ngIf=\"firstValue\">\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{ item?.department_name || item?.roleName || \"-\" }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) ? (getNestedValue(row, col.field) | date:'shortDate') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ getNestedValue(row, col.field) ? (getNestedValue(row, col.field) | date:'shortTime') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) === true || getNestedValue(row, col.field) === 'true') ? 'bg-success' : 'bg-secondary'\">\r\n {{ (getNestedValue(row, col.field) === true || getNestedValue(row, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field))\">\r\n {{ (getNestedValue(row, col.field) || []).length }} items\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field))\">\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n \r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\r\n>\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Manual Logs Modal -->\r\n<div *ngIf=\"showManualLogsModal\" class=\"custom-modal-overlay\">\r\n <div class=\"custom-modal-content manual-logs-modal\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Manual Logs Details</h5>\r\n <button type=\"button\" class=\"btn-close\" (click)=\"closeManualLogsModal()\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous Time</th>\r\n <th>Updated Time</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <!-- Display manually_logs if available - Show ALL entries -->\r\n <ng-container *ngIf=\"currentManualLogsRow?.manually_logs && currentManualLogsRow.manually_logs.length > 0\">\r\n <ng-container *ngFor=\"let item of currentManualLogsRow.manually_logs; let i = index\">\r\n <!-- Clock In Row - Show even if status is null or has data -->\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_in?.previous_state && item.clock_in.previous_state !== 'Absent' && item.clock_in.previous_state !== '-' ? (item.clock_in.previous_state | date:'short') : (item.clock_in.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_in?.time && item.clock_in.time !== 'Absent' && item.clock_in.time !== null && item.clock_in.time !== '_' ? (item.clock_in.time | date:'short') : (item.clock_in.time || '-') }}</td>\r\n <td>{{ item?.clock_in?.status ? transformStatus(item.clock_in.status) : (item.clock_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Clock Out Row - Show even if status is null or has data -->\r\n <tr *ngIf=\"item.clock_out\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_out?.previous_state && item.clock_out.previous_state !== 'Absent' && item.clock_out.previous_state !== '-' ? (item.clock_out.previous_state | date:'short') : (item.clock_out.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_out?.time && item.clock_out.time !== 'Absent' && item.clock_out.time !== null && item.clock_out.time !== '_' ? (item.clock_out.time | date:'short') : (item.clock_out.time || '-') }}</td>\r\n <td>{{ item?.clock_out?.status ? transformStatus(item.clock_out.status) : (item.clock_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Handle breaks -->\r\n <ng-container *ngIf=\"item.breaks && item.breaks.length > 0\">\r\n <ng-container *ngFor=\"let breakItem of item.breaks\">\r\n <!-- Break In -->\r\n <tr *ngIf=\"breakItem?.break_in\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_in?.previous_state && breakItem.break_in.previous_state !== 'Absent' && breakItem.break_in.previous_state !== '-' ? (breakItem.break_in.previous_state | date:'short') : (breakItem.break_in.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.time && breakItem.break_in.time !== 'Absent' && breakItem.break_in.time !== null && breakItem.break_in.time !== '_' ? (breakItem.break_in.time | date:'short') : (breakItem.break_in.time || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.status ? transformStatus(breakItem.break_in.status) : (breakItem.break_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Break Out -->\r\n <tr *ngIf=\"breakItem?.break_out\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_out?.previous_state && breakItem.break_out.previous_state !== 'Absent' && breakItem.break_out.previous_state !== '-' ? (breakItem.break_out.previous_state | date:'short') : (breakItem.break_out.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.time && breakItem.break_out.time !== 'Absent' && breakItem.break_out.time !== null && breakItem.break_out.time !== '_' ? (breakItem.break_out.time | date:'short') : (breakItem.break_out.time || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.status ? transformStatus(breakItem.break_out.status) : (breakItem.break_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Fallback to logs array if manually_logs is empty -->\r\n <ng-container *ngIf=\"(!currentManualLogsRow?.manually_logs || currentManualLogsRow.manually_logs.length === 0) && currentManualLogsRow?.logs\">\r\n <ng-container *ngFor=\"let log of currentManualLogsRow.logs; let i = index\">\r\n <tr>\r\n <td>{{ currentManualLogsRow?.User?.full_name || currentManualLogsRow?.attendance_adjusted_by?.full_name || '-' }}</td>\r\n <td>{{ log?.log_date ? (log.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ currentManualLogsRow?.clock_in_time && currentManualLogsRow.clock_in_time !== 'Absent' ? (currentManualLogsRow.clock_in_time | date:'shortTime') : '-' }}</td>\r\n <td>{{ currentManualLogsRow?.clock_out_time && currentManualLogsRow.clock_out_time !== 'Absent' ? (currentManualLogsRow.clock_out_time | date:'shortTime') : '-' }}</td>\r\n <td>{{ log?.log_status ? transformStatus(log.log_status) : currentManualLogsRow?.attendanceStatus || '-' }}</td>\r\n <td>{{ currentManualLogsRow?.message || log?.remarks || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Show message if no data available -->\r\n <tr *ngIf=\"(!currentManualLogsRow?.manually_logs || currentManualLogsRow.manually_logs.length === 0) && (!currentManualLogsRow?.logs || currentManualLogsRow.logs.length === 0)\">\r\n <td colspan=\"6\" class=\"text-center text-muted\">No manual log details available</td>\r\n </tr>\r\n\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Modal overlay for accordion manual logs tooltip -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"manual-logs-modal-overlay\" (click)=\"hideManualLogsTooltip()\">\r\n <div class=\"manual-logs-modal-content\" (click)=\"$event.stopPropagation()\" (mouseenter)=\"preventManualLogsTooltipHide()\" (mouseleave)=\"hideManualLogsTooltip()\">\r\n <div class=\"modal-header\">\r\n <h5>Manual Logs Details</h5>\r\n <button type=\"button\" class=\"close\" (click)=\"hideManualLogsTooltip()\">&times;</button>\r\n </div>\r\n <div class=\"modal-body\" style=\"max-height: 400px; overflow-y: auto;\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous Time</th>\r\n <th>Updated Time</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <!-- Clock In Row -->\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_in?.previous_state && item.clock_in.previous_state !== 'Absent' && item.clock_in.previous_state !== '-' ? (item.clock_in.previous_state | date:'short') : (item.clock_in.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_in?.time && item.clock_in.time !== 'Absent' && item.clock_in.time !== null && item.clock_in.time !== '_' ? (item.clock_in.time | date:'short') : (item.clock_in.time || '-') }}</td>\r\n <td>{{ item?.clock_in?.status ? transformStatus(item.clock_in.status) : (item.clock_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Clock Out Row -->\r\n <tr *ngIf=\"item.clock_out\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_out?.previous_state && item.clock_out.previous_state !== 'Absent' && item.clock_out.previous_state !== '-' ? (item.clock_out.previous_state | date:'short') : (item.clock_out.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_out?.time && item.clock_out.time !== 'Absent' && item.clock_out.time !== null && item.clock_out.time !== '_' ? (item.clock_out.time | date:'short') : (item.clock_out.time || '-') }}</td>\r\n <td>{{ item?.clock_out?.status ? transformStatus(item.clock_out.status) : (item.clock_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Breaks -->\r\n <ng-container *ngIf=\"item.breaks && item.breaks.length > 0\">\r\n <ng-container *ngFor=\"let breakItem of item.breaks\">\r\n <tr *ngIf=\"breakItem?.break_in\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_in?.previous_state && breakItem.break_in.previous_state !== 'Absent' && breakItem.break_in.previous_state !== '-' ? (breakItem.break_in.previous_state | date:'short') : (breakItem.break_in.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.time && breakItem.break_in.time !== 'Absent' && breakItem.break_in.time !== null && breakItem.break_in.time !== '_' ? (breakItem.break_in.time | date:'short') : (breakItem.break_in.time || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.status ? transformStatus(breakItem.break_in.status) : (breakItem.break_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <tr *ngIf=\"breakItem?.break_out\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_out?.previous_state && breakItem.break_out.previous_state !== 'Absent' && breakItem.break_out.previous_state !== '-' ? (breakItem.break_out.previous_state | date:'short') : (breakItem.break_out.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.time && breakItem.break_out.time !== 'Absent' && breakItem.break_out.time !== null && breakItem.break_out.time !== '_' ? (breakItem.break_out.time | date:'short') : (breakItem.break_out.time || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.status ? transformStatus(breakItem.break_out.status) : (breakItem.break_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #detailModalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative}.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: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: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:80px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;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:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height: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:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.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}.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{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.circle-value{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;background-color:#f0f0f0;border:1px solid #ccc;font-size:12px;font-weight:700;color:#333;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .2s ease}.circle-value:hover{background-color:#d9d9d9;box-shadow:0 2px 4px #0000001a;transform:scale(1.1)}.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:background-color .2s ease;font-size:14px}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{position:absolute;top:0;right:-4px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:40;transition:opacity .2s;background:transparent}th:hover .resize-handle{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .2s ease}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.05)}.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-datepicker-head{background:linear-gradient(135deg,#4361ee,#3a0ca3)!important;color:#fff!important;border-radius:12px 12px 0 0!important;padding:16px 20px!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#fff!important;font-size:16px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff3!important;color:#fff!important;border:none!important;width:32px!important;height:32px!important;border-radius:50%!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#ffffff4d!important;transform:scale(1.05)}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:16px!important;background:#f8f9fa!important;border-top:1px solid #e9ecef!important;border-radius:0 0 12px 12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#4361ee,#3a0ca3)!important;color:#fff!important;border:none!important;box-shadow:0 4px 10px #4361ee4d!important;font-weight:600!important;padding:8px 16px!important;border-radius:8px!important;transition:all .2s ease!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{transform:translateY(-2px)!important;box-shadow:0 6px 14px #4361ee66!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #ced4da!important;font-weight:600!important;padding:8px 16px!important;border-radius:8px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#f1f3f5!important;color:#212529!important;border-color:#adb5bd!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))}.popver_content_progress_bar{visibility:hidden}.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;transition:background-color .2s ease}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item:hover,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item:hover,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item:hover,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item:hover{background-color:#007bff1a}.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}}\n"] }]
7477
+ ], template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n \r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <!-- Email Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"onEmailClick()\"\r\n title=\"Email\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/smsIcon.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Email</span>\r\n</a>\r\n\r\n<!-- Add Attendance Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onAddAttendanceClick()\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/addAttendenceIcon.svg'\"\r\n class=\"svg-icon svg-icon-2 pe-2\"\r\n ></span>\r\n Add Attendance\r\n</a>\r\n\r\n<!-- Back Pay Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onBackPayClick()\"\r\n title=\"Back Pay\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/back pay.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Back pay</span>\r\n</a>\r\n\r\n<!-- Grand Total Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onGrandTotalClick()\"\r\n title=\"Grand Total\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/grandtotal.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Grand totel</span>\r\n</a>\r\n\r\n<!-- Print Button -->\r\n<a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onPrintClick()\"\r\n title=\"Print\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/svg/New/printIcon.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Print</span>\r\n</a>\r\n\r\n<!-- Export Button (Multi-day) -->\r\n<a\r\n *ngIf=\"!isSingleDay\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onExportClick()\"\r\n title=\"Export\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/general/export.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Export</span>\r\n</a>\r\n\r\n<!-- Export Daily Timesheet (Single-day) -->\r\n<a\r\n *ngIf=\"isSingleDay\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-sm btn btn-active-primary border border-primary me-2 header-icon filter-btn\"\r\n (click)=\"onExportDailyClick()\"\r\n title=\"Export Daily Timesheet\"\r\n>\r\n <span\r\n [inlineSVG]=\"'../../../../../../assets/media/icons/techbar/general/export.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Export Daily Timesheet</span>\r\n</a>\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n<div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 2px;\r\n top: 2px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n</div>\r\n<!-- <div\r\n class=\"cursor-pointer\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n</div> -->\r\n<div\r\n class=\"cursor-pointer\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a class=\"dropdown-item\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a class=\"dropdown-item\" (click)=\"downloadCsv()\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Download as CSV\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div class=\"d-flex gap-2 align-items-center me-5\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n \r\n\r\n \r\n <div class=\"position-relative d-inline-block ms-5\">\r\n \r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n \r\n <!-- Calendar Icon -->\r\n\r\n <!-- <div class=\"icon-container position-absolute end-0 top-50 translate-middle-y me-2\"\r\n (click)=\"togglePicker(picker)\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/calendar.svg'\"\r\n class=\"data-grid-svg-icon top-icon\"\r\n style=\"cursor: pointer;\"\r\n ></span>\r\n </div> -->\r\n <!-- Calendar Button -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-xs btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Calendar\"\r\n >\r\n <span class=\"bi bi-calendar me-1\"></span>\r\n Calendar\r\n </a>\r\n\r\n <!-- Clear Button -->\r\n <a\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n href=\"JavaScript:void(0)\"\r\n class=\"button btn-xs btn btn-outline-danger border border-danger me-2 header-icon\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date\"\r\n >\r\n <span class=\"bi bi-x-circle me-1\"></span>\r\n Clear\r\n </a>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-muted ms-2 me-3\"\r\n style=\"font-size: 14px; font-weight: 500;\"\r\n >\r\n {{ bsRangeValue[0] | date:'shortDate' }} - {{ bsRangeValue[1] | date:'shortDate' }}\r\n </span>\r\n \r\n </div>\r\n\r\n </div>\r\n <div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"65\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n ></div>\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterHeaderScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"openThreeDotsMenu($event, 'group')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"onResizeGroupBox($event)\"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <!-- <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div [style.width.px]=\"30\"></div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'previewRightPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet.length && !loading\"\r\n >\r\n No Record Found\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n <div\r\n *ngIf=\"false\"\r\n class=\"card-view-container p-3\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n >\r\n <div class=\"row g-3\">\r\n <div\r\n *ngFor=\"let row of dataSet; let i = index; trackBy: trackById\"\r\n class=\"col-xl-4 col-lg-6 col-md-6 col-sm-12\"\r\n >\r\n <div class=\"card h-100 shadow-sm attendance-card\" [class.expanded]=\"row.isCardExpanded\">\r\n <!-- Card Header -->\r\n <div class=\"card-header d-flex align-items-center p-3\">\r\n <div class=\"employee-avatar me-3\">\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <img\r\n [width]=\"40\"\r\n [height]=\"40\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"avatar\"\r\n class=\"rounded-circle\"\r\n />\r\n </ng-container>\r\n <ng-template #placeholder>\r\n <div\r\n class=\"avatar-placeholder rounded-circle d-flex align-items-center justify-content-center text-white fw-bold\"\r\n [style.width.px]=\"40\"\r\n [style.height.px]=\"40\"\r\n [style.fontSize.px]=\"16\"\r\n [style.backgroundColor]=\"getAvatarColor(row?.User?.full_name || row?.full_name || row?.name)\"\r\n >\r\n {{ getInitialss(row?.User?.full_name || row?.full_name || row?.name) }}\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <h6 class=\"mb-1 fw-bold\">{{ row?.User?.full_name || row?.full_name || row?.name || 'N/A' }}</h6>\r\n <small class=\"text-muted\">{{ row?.attendanceDate | date:'mediumDate' }}</small>\r\n </div>\r\n <div class=\"card-actions\">\r\n <button\r\n class=\"btn btn-sm btn-outline-primary\"\r\n (click)=\"row.isCardExpanded = !row.isCardExpanded\"\r\n [title]=\"row.isCardExpanded ? 'Collapse' : 'Expand'\"\r\n >\r\n <i class=\"bi\" [class]=\"row.isCardExpanded ? 'bi-chevron-up' : 'bi-chevron-down'\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Card Body -->\r\n <div class=\"card-body p-3\">\r\n <!-- Basic Attendance Info -->\r\n <div class=\"row g-2 mb-3\">\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock In</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_in_time ? (row.clock_in_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Clock Out</small>\r\n <span class=\"fw-semibold\">{{ row?.clock_out_time ? (row.clock_out_time | date:'shortTime') : '--:--' }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Total Hours</small>\r\n <span class=\"fw-semibold\">{{ calculateTotalHours(row) }}</span>\r\n </div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"info-item\">\r\n <small class=\"text-muted d-block\">Status</small>\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(row?.attendanceStatus)\">{{ row?.attendanceStatus || 'Unknown' }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Expandable Details -->\r\n <div class=\"card-details\" *ngIf=\"row.isCardExpanded\">\r\n <hr class=\"my-3\">\r\n\r\n <!-- All Column Data Section -->\r\n <div class=\"all-columns-section mb-3\">\r\n <h6 class=\"section-title mb-3\">\r\n <i class=\"bi bi-table me-2\"></i>All Details\r\n </h6>\r\n <div class=\"row g-2\">\r\n <ng-container *ngFor=\"let col of centerColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of leftPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let col of rightPinnedColumns; trackBy: trackByField\">\r\n <div class=\"col-md-6 col-lg-4\" *ngIf=\"col.is_visible !== false\">\r\n <div class=\"column-data-item p-2 border rounded\">\r\n <small class=\"text-muted d-block fw-semibold\">{{ col.header }}</small>\r\n <span class=\"fw-medium\">\r\n <ng-container *ngTemplateOutlet=\"cellContent; context: { row: row, col: col }\"></ng-container>\r\n </span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Breaks Section -->\r\n <div class=\"breaks-section mb-3\" *ngIf=\"row?.breaks?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-clock-history me-2\"></i>Breaks\r\n </h6>\r\n <div class=\"breaks-list\">\r\n <div\r\n *ngFor=\"let breakItem of row.breaks; let bIndex = index\"\r\n class=\"break-item p-2 border rounded mb-2\"\r\n [title]=\"getBreakTooltip(breakItem)\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ breakItem?.break_type?.data_value_name || ('Break ' + (bIndex + 1)) }}</small>\r\n <div class=\"text-muted small\">\r\n {{ breakItem?.break_in_time ? (breakItem.break_in_time | date:'shortTime') : '--:--' }} -\r\n {{ breakItem?.break_out_time ? (breakItem.break_out_time | date:'shortTime') : '--:--' }}\r\n </div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-info\">{{ breakItem?.break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Breaks Section -->\r\n <div class=\"short-breaks-section mb-3\" *ngIf=\"row?.short_breaks\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pause-circle me-2\"></i>Short Breaks\r\n </h6>\r\n <div class=\"short-break-item p-2 border rounded\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ row.short_breaks?.short_break_name || 'Quick Break' }}</small>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-warning\">{{ row.short_breaks?.short_break_duration || 0 }}m</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Short Leave Section -->\r\n <div class=\"short-leave-section mb-3\" *ngIf=\"row?.short_leave?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-calendar-x me-2\"></i>Short Leave\r\n </h6>\r\n <div class=\"short-leave-list\">\r\n <div\r\n *ngFor=\"let leave of row.short_leave\"\r\n class=\"leave-item p-2 border rounded mb-2\"\r\n >\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div>\r\n <small class=\"fw-semibold\">{{ leave?.leave_type || 'Leave' }}</small>\r\n <div class=\"text-muted small\">{{ leave?.minutes || 0 }} minutes</div>\r\n </div>\r\n <div class=\"text-end\">\r\n <span class=\"badge bg-danger\">Leave</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Manual Logs Section -->\r\n <div class=\"manual-logs-section mb-3\" *ngIf=\"row?.manually_logs?.length\">\r\n <h6 class=\"section-title mb-2\">\r\n <i class=\"bi bi-pencil-square me-2\"></i>Manual Logs\r\n </h6>\r\n <button\r\n class=\"btn btn-sm btn-outline-info\"\r\n (click)=\"openManualLogsModal($event, row)\"\r\n title=\"View Manual Logs Details\"\r\n >\r\n <i class=\"bi bi-eye me-1\"></i>View Details\r\n </button>\r\n </div>\r\n\r\n <!-- Additional Details -->\r\n <div class=\"additional-details\">\r\n <div class=\"row g-2\">\r\n <div class=\"col-6\" *ngIf=\"row?.overtime_hours\">\r\n <small class=\"text-muted d-block\">Overtime</small>\r\n <span class=\"fw-semibold\">{{ row.overtime_hours }}h</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.late_minutes\">\r\n <small class=\"text-muted d-block\">Late Minutes</small>\r\n <span class=\"fw-semibold\">{{ row.late_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.early_departure_minutes\">\r\n <small class=\"text-muted d-block\">Early Departure</small>\r\n <span class=\"fw-semibold\">{{ row.early_departure_minutes }}m</span>\r\n </div>\r\n <div class=\"col-6\" *ngIf=\"row?.message\">\r\n <small class=\"text-muted d-block\">Remarks</small>\r\n <span class=\"fw-semibold text-truncate d-block\" [title]=\"row.message\">{{ row.message }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table View -->\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length) + (hasMoreData ? 1000 : 0)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onHorizintalFakeScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, child)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"onResizeColumn($event, child)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div class=\"group-column-wrapper\">\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"onResizeColumn($event, col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"65\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"65\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n </div>\r\n <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4 border-right\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (click)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on me-2 text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <div class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeavePopover($event, d)\"\r\n (mouseleave)=\"hideShortLeavePopover()\">\r\n <span class=\"d-block\"\r\n [style.min-width.%]=\"(d.short_leave && d.short_leave.length > 0) ? d.short_leave[0].short_leave_time_percentage : 0\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ (d.short_leave && d.short_leave.length > 0) ? d.short_leave[0].short_leave_time_percentage : 0 }}%</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [ngClass]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [ngClass]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { \r\n break_duration: 0, \r\n break_type: { data_value_name: 'No Break' }, \r\n breakInstatus: 'None',\r\n break_in_time: null,\r\n break_out_time: null\r\n })\"\r\n (mouseleave)=\"hideBreakTooltip()\"\r\n >\r\n 0m\r\n </div>\r\n</ng-template>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeavePopover($event, d)\"\r\n (mouseleave)=\"hideShortLeavePopover()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <!-- <ng-template #noShortLeaveDetail>\r\n <div class=\"circle-value\">0%</div>\r\n </ng-template> -->\r\n </div>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (click)=\"showManualLogsTooltip($event, row, d)\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"rowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (click)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"badge badge-circle circle-value badge-outline break-on me-2 text-center popover__wrapper\"\r\n [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div class=\"circle-value text-muted\"\r\n (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [style.backgroundColor]=\"getBreakColor(d[col.field].type)\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div class=\"circle-value\"\r\n (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveLeft\">\r\n <div class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\">\r\n <span class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <!-- <ng-template #noShortLeaveLeft>\r\n <div class=\"circle-value\">0%</div>\r\n </ng-template> -->\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col.type === 'date'\r\n ? (getNestedValue(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <div class=\"d-flex justify-content-center align-items-center flex-wrap gap-1\">\r\n <span *ngFor=\"let breakItem of getNestedValue(row, 'breaks'); trackBy: trackById\" class=\"popover__wrapper\" (mouseenter)=\"showBreakTooltip($event, breakItem)\" (mouseleave)=\"hideBreakTooltip()\">\r\n <span class=\"circle-value badge-outline break-on text-center\" [style.backgroundColor]=\"getBreakColor(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase())\">\r\n {{ breakItem.break_duration }}m\r\n </span>\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div class=\"circle-value text-muted text-center\" (mouseenter)=\"showBreakTooltip($event, { break_duration: 0, break_type: { data_value_name: 'No Break' }, breakInstatus: 'None', break_in_time: null, break_out_time: null })\" (mouseleave)=\"hideBreakTooltip()\">\r\n 0m\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [style.backgroundColor]=\"getBreakColor(row.short_breaks.type)\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div class=\"circle-value text-center\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, {duration: 0, type: 'none'}, 'single_break'); preventCustomTooltipHide()\" (mouseleave)=\"hideShortBreakTooltip()\">0m</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <ng-container *ngSwitchCase=\"'short_leave'\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\" (mouseenter)=\"showShortLeavePopover($event, row)\" (mouseleave)=\"hideShortLeavePopover()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"(row.short_leave && row.short_leave.length > 0) ? row.short_leave[0].short_leave_time_percentage : 0\" style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ (row.short_leave && row.short_leave.length > 0) ? row.short_leave[0].short_leave_time_percentage : 0 }}%</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [ngClass]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [ngClass]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? (getNestedValue(row, col.field) | date: dateFormat)\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\" (mouseleave)=\"hideManualLogsTooltip()\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon -->\r\n <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> In: {{ currentBreakTooltip.break_in_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> Out: {{ currentBreakTooltip.break_out_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentBreakTooltip.break_duration }} min</div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n <div class=\"break-tooltip-body\">\r\n <div><i class=\"bi bi-play-circle\"></i> Start: {{ currentShortBreakTooltip.start_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-stop-circle\"></i> End: {{ currentShortBreakTooltip.end_time | date:'shortTime' }}</div>\r\n <div><i class=\"bi bi-clock\"></i> Duration: {{ currentShortBreakTooltip.short_break_duration }} min</div>\r\n </div>\r\n</div>\r\n\r\n\r\n<!-- Short Leave Popover (Detail Rows) -->\r\n<div\r\n *ngIf=\"isShortLeavePopoverVisible\"\r\n class=\"popver_content_progress_bar\"\r\n [style.position]=\"'fixed'\"\r\n [style.top.px]=\"shortLeaveTooltipPosition.y + 10\"\r\n [style.left.px]=\"shortLeaveTooltipPosition.x\"\r\n style=\"z-index: 1000; background: white; border: 1px solid #ddd; border-radius: 6px; padding: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); width: 250px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area\">\r\n <div class=\"table-responsive iis-scrollbar table-container\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-3\" style=\"font-size: xx-small;\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 20%;\">Leave Type</th>\r\n <th class=\"center\">Start</th>\r\n <th class=\"center\">End</th>\r\n <th class=\"center\">Duration</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let leave of currentShortLeaveData\">\r\n <td class=\"center\">{{ leave.leave_type || 'Short Leave' }}</td>\r\n <td class=\"center\">{{ leave.star_time || leave.start_time || '\u2013' }}</td>\r\n <td class=\"center\">{{ leave.end_time || '\u2013' }}</td>\r\n <td class=\"center\">{{ leave.hours }}H {{ leave.minutes % 60 }}M</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" [class.visually-hidden]=\"isMenueHidden\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col.query.first_value\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container *ngIf=\"col.query?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n />\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n</div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation();\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save Preset\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div class=\"\">\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <span\r\n *ngIf=\"!tableFilterViewId\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"clearAllFilters()\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\"\r\n >Created {{ table?.createdAt | date : \"MMM d, y\" }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\r\n >\r\n <div class=\"muted-text show-hide-table-label\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n />\r\n </div>\r\n <div *ngIf=\"firstValue\">\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{ item?.department_name || item?.roleName || \"-\" }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | date:'shortDate') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | date:'shortTime') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'bg-success' : 'bg-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [ngClass]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\r\n>\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Manual Logs Modal -->\r\n<div *ngIf=\"showManualLogsModal\" class=\"custom-modal-overlay\">\r\n <div class=\"custom-modal-content manual-logs-modal\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title\">Manual Logs Details</h5>\r\n <button type=\"button\" class=\"btn-close\" (click)=\"closeManualLogsModal()\"></button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous Time</th>\r\n <th>Updated Time</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <!-- Display manually_logs if available - Show ALL entries -->\r\n <ng-container *ngIf=\"currentManualLogsRow?.manually_logs && currentManualLogsRow.manually_logs.length > 0\">\r\n <ng-container *ngFor=\"let item of currentManualLogsRow.manually_logs; let i = index\">\r\n <!-- Clock In Row - Show even if status is null or has data -->\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_in?.previous_state && item.clock_in.previous_state !== 'Absent' && item.clock_in.previous_state !== '-' ? (item.clock_in.previous_state | date:'short') : (item.clock_in.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_in?.time && item.clock_in.time !== 'Absent' && item.clock_in.time !== null && item.clock_in.time !== '_' ? (item.clock_in.time | date:'short') : (item.clock_in.time || '-') }}</td>\r\n <td>{{ item?.clock_in?.status ? transformStatus(item.clock_in.status) : (item.clock_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Clock Out Row - Show even if status is null or has data -->\r\n <tr *ngIf=\"item.clock_out\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_out?.previous_state && item.clock_out.previous_state !== 'Absent' && item.clock_out.previous_state !== '-' ? (item.clock_out.previous_state | date:'short') : (item.clock_out.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_out?.time && item.clock_out.time !== 'Absent' && item.clock_out.time !== null && item.clock_out.time !== '_' ? (item.clock_out.time | date:'short') : (item.clock_out.time || '-') }}</td>\r\n <td>{{ item?.clock_out?.status ? transformStatus(item.clock_out.status) : (item.clock_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Handle breaks -->\r\n <ng-container *ngIf=\"item.breaks && item.breaks.length > 0\">\r\n <ng-container *ngFor=\"let breakItem of item.breaks\">\r\n <!-- Break In -->\r\n <tr *ngIf=\"breakItem?.break_in\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_in?.previous_state && breakItem.break_in.previous_state !== 'Absent' && breakItem.break_in.previous_state !== '-' ? (breakItem.break_in.previous_state | date:'short') : (breakItem.break_in.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.time && breakItem.break_in.time !== 'Absent' && breakItem.break_in.time !== null && breakItem.break_in.time !== '_' ? (breakItem.break_in.time | date:'short') : (breakItem.break_in.time || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.status ? transformStatus(breakItem.break_in.status) : (breakItem.break_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Break Out -->\r\n <tr *ngIf=\"breakItem?.break_out\">\r\n <td>{{ item?.updated_by?.full_name || currentManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_out?.previous_state && breakItem.break_out.previous_state !== 'Absent' && breakItem.break_out.previous_state !== '-' ? (breakItem.break_out.previous_state | date:'short') : (breakItem.break_out.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.time && breakItem.break_out.time !== 'Absent' && breakItem.break_out.time !== null && breakItem.break_out.time !== '_' ? (breakItem.break_out.time | date:'short') : (breakItem.break_out.time || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.status ? transformStatus(breakItem.break_out.status) : (breakItem.break_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || currentManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Fallback to logs array if manually_logs is empty -->\r\n <ng-container *ngIf=\"(!currentManualLogsRow?.manually_logs || currentManualLogsRow.manually_logs.length === 0) && currentManualLogsRow?.logs\">\r\n <ng-container *ngFor=\"let log of currentManualLogsRow.logs; let i = index\">\r\n <tr>\r\n <td>{{ currentManualLogsRow?.User?.full_name || currentManualLogsRow?.attendance_adjusted_by?.full_name || '-' }}</td>\r\n <td>{{ log?.log_date ? (log.log_date | date:'short') : (currentManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ currentManualLogsRow?.clock_in_time && currentManualLogsRow.clock_in_time !== 'Absent' ? (currentManualLogsRow.clock_in_time | date:'shortTime') : '-' }}</td>\r\n <td>{{ currentManualLogsRow?.clock_out_time && currentManualLogsRow.clock_out_time !== 'Absent' ? (currentManualLogsRow.clock_out_time | date:'shortTime') : '-' }}</td>\r\n <td>{{ log?.log_status ? transformStatus(log.log_status) : currentManualLogsRow?.attendanceStatus || '-' }}</td>\r\n <td>{{ currentManualLogsRow?.message || log?.remarks || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Show message if no data available -->\r\n <tr *ngIf=\"(!currentManualLogsRow?.manually_logs || currentManualLogsRow.manually_logs.length === 0) && (!currentManualLogsRow?.logs || currentManualLogsRow.logs.length === 0)\">\r\n <td colspan=\"6\" class=\"text-center text-muted\">No manual log details available</td>\r\n </tr>\r\n\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Modal overlay for accordion manual logs tooltip -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"manual-logs-modal-overlay\" (click)=\"hideManualLogsTooltip()\">\r\n <div class=\"manual-logs-modal-content\" (click)=\"$event.stopPropagation()\" (mouseenter)=\"preventManualLogsTooltipHide()\" (mouseleave)=\"hideManualLogsTooltip()\">\r\n <div class=\"modal-header\">\r\n <h5>Manual Logs Details</h5>\r\n <button type=\"button\" class=\"close\" (click)=\"hideManualLogsTooltip()\">&times;</button>\r\n </div>\r\n <div class=\"modal-body\" style=\"max-height: 400px; overflow-y: auto;\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous Time</th>\r\n <th>Updated Time</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <!-- Clock In Row -->\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_in?.previous_state && item.clock_in.previous_state !== 'Absent' && item.clock_in.previous_state !== '-' ? (item.clock_in.previous_state | date:'short') : (item.clock_in.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_in?.time && item.clock_in.time !== 'Absent' && item.clock_in.time !== null && item.clock_in.time !== '_' ? (item.clock_in.time | date:'short') : (item.clock_in.time || '-') }}</td>\r\n <td>{{ item?.clock_in?.status ? transformStatus(item.clock_in.status) : (item.clock_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Clock Out Row -->\r\n <tr *ngIf=\"item.clock_out\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ item?.clock_out?.previous_state && item.clock_out.previous_state !== 'Absent' && item.clock_out.previous_state !== '-' ? (item.clock_out.previous_state | date:'short') : (item.clock_out.previous_state || '-') }}</td>\r\n <td>{{ item?.clock_out?.time && item.clock_out.time !== 'Absent' && item.clock_out.time !== null && item.clock_out.time !== '_' ? (item.clock_out.time | date:'short') : (item.clock_out.time || '-') }}</td>\r\n <td>{{ item?.clock_out?.status ? transformStatus(item.clock_out.status) : (item.clock_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <!-- Breaks -->\r\n <ng-container *ngIf=\"item.breaks && item.breaks.length > 0\">\r\n <ng-container *ngFor=\"let breakItem of item.breaks\">\r\n <tr *ngIf=\"breakItem?.break_in\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_in?.previous_state && breakItem.break_in.previous_state !== 'Absent' && breakItem.break_in.previous_state !== '-' ? (breakItem.break_in.previous_state | date:'short') : (breakItem.break_in.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.time && breakItem.break_in.time !== 'Absent' && breakItem.break_in.time !== null && breakItem.break_in.time !== '_' ? (breakItem.break_in.time | date:'short') : (breakItem.break_in.time || '-') }}</td>\r\n <td>{{ breakItem?.break_in?.status ? transformStatus(breakItem.break_in.status) : (breakItem.break_in?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n <tr *ngIf=\"breakItem?.break_out\">\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date ? (item.log_date | date:'short') : (selectedManualLogsRow?.attendanceDate | date:'short') }}</td>\r\n <td>{{ breakItem?.break_out?.previous_state && breakItem.break_out.previous_state !== 'Absent' && breakItem.break_out.previous_state !== '-' ? (breakItem.break_out.previous_state | date:'short') : (breakItem.break_out.previous_state || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.time && breakItem.break_out.time !== 'Absent' && breakItem.break_out.time !== null && breakItem.break_out.time !== '_' ? (breakItem.break_out.time | date:'short') : (breakItem.break_out.time || '-') }}</td>\r\n <td>{{ breakItem?.break_out?.status ? transformStatus(breakItem.break_out.status) : (breakItem.break_out?.status || '-') }}</td>\r\n <td>{{ item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #detailModalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative}.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: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: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:80px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;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:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height: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:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.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}.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{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.circle-value{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;background-color:#f0f0f0;border:1px solid #ccc;font-size:12px;font-weight:700;color:#333;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .2s ease}.circle-value:hover{background-color:#d9d9d9;box-shadow:0 2px 4px #0000001a;transform:scale(1.1)}.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:background-color .2s ease;font-size:14px}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{position:absolute;top:0;right:-4px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:40;transition:opacity .2s;background:transparent}th:hover .resize-handle{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .2s ease}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.05)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;height:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{background:#fff!important;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))}.popver_content_progress_bar{visibility:hidden}.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;transition:background-color .2s ease}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item:hover,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item:hover,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item:hover,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item:hover{background-color:#007bff1a}.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}\n"] }]
7615
7478
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ViewContainerRef }], propDecorators: { onShortBreakClick: [{
7616
7479
  type: Output
7617
7480
  }], searchEvent: [{
@@ -7880,6 +7743,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7880
7743
  type: Output
7881
7744
  }], exportDailyClicked: [{
7882
7745
  type: Output
7746
+ }], deleteClicked: [{
7747
+ type: Output
7883
7748
  }] } });
7884
7749
 
7885
7750
  /*