ms-time-sheet 0.0.10 → 0.0.12

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.
@@ -716,6 +716,159 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
716
716
  args: [{ name: 'pinnedColumns', pure: true, standalone: true }]
717
717
  }] });
718
718
 
719
+ class TimezoneFormatPipe {
720
+ constructor() {
721
+ this.formatCache = new Map();
722
+ }
723
+ transform(value, prefs, formatType = 'datetime') {
724
+ if (!value) {
725
+ return '';
726
+ }
727
+ const timeZone = prefs?.timeZone || 'America/New_York';
728
+ // Convert Angular DatePipe format to moment.js format for parsing
729
+ const dateFormat = this.convertAngularToMomentFormat(prefs?.dateFormat || 'MM/dd/yyyy');
730
+ const timeFormat = this.convertAngularToMomentFormat(prefs?.timeFormat || 'HH:mm');
731
+ // Detect if value is time-only (e.g. '09:00', '9:00', '09:00:00' format)
732
+ const isTimeOnly = /^\d{1,2}:\d{2}(:\d{2})?$/.test(String(value));
733
+ let finalFormat;
734
+ if (formatType === 'date') {
735
+ finalFormat = dateFormat;
736
+ }
737
+ else if (formatType === 'time') {
738
+ finalFormat = timeFormat;
739
+ }
740
+ else {
741
+ finalFormat = `${dateFormat} ${timeFormat}`;
742
+ }
743
+ let date;
744
+ if (isTimeOnly) {
745
+ // Combine with today's date for timezone context
746
+ const today = new Date().toISOString().split('T')[0];
747
+ const timeStr = String(value);
748
+ // Ensure time has seconds if not present
749
+ const fullTimeStr = timeStr.includes(':') && timeStr.split(':').length === 2 ? `${timeStr}:00` : timeStr;
750
+ const dateTimeString = `${today}T${fullTimeStr}`;
751
+ date = new Date(dateTimeString);
752
+ }
753
+ else {
754
+ // Parse as date
755
+ if (value instanceof Date) {
756
+ date = value;
757
+ }
758
+ else {
759
+ date = new Date(value);
760
+ }
761
+ if (isNaN(date.getTime())) {
762
+ return '';
763
+ }
764
+ }
765
+ return this.formatDate(date, finalFormat, timeZone);
766
+ }
767
+ formatDate(date, format, timeZone) {
768
+ const options = this.parseFormatToIntlOptions(format);
769
+ options.timeZone = timeZone;
770
+ const formatter = new Intl.DateTimeFormat('en-US', options);
771
+ return formatter.format(date);
772
+ }
773
+ parseFormatToIntlOptions(format) {
774
+ const cacheKey = format;
775
+ if (this.formatCache.has(cacheKey)) {
776
+ return { ...this.formatCache.get(cacheKey) };
777
+ }
778
+ const options = {};
779
+ // Parse moment.js style format strings
780
+ // Handle year
781
+ if (format.includes('YYYY')) {
782
+ options.year = 'numeric';
783
+ }
784
+ else if (format.includes('YY')) {
785
+ options.year = '2-digit';
786
+ }
787
+ // Handle month
788
+ if (format.includes('MMMM')) {
789
+ options.month = 'long';
790
+ }
791
+ else if (format.includes('MMM')) {
792
+ options.month = 'short';
793
+ }
794
+ else if (format.includes('MM')) {
795
+ options.month = '2-digit';
796
+ }
797
+ else if (format.includes('M')) {
798
+ options.month = 'numeric';
799
+ }
800
+ // Handle day
801
+ if (format.includes('DD')) {
802
+ options.day = '2-digit';
803
+ }
804
+ else if (format.includes('D')) {
805
+ options.day = 'numeric';
806
+ }
807
+ // Handle weekday
808
+ if (format.includes('dddd')) {
809
+ options.weekday = 'long';
810
+ }
811
+ else if (format.includes('ddd')) {
812
+ options.weekday = 'short';
813
+ }
814
+ // Handle hour
815
+ if (format.includes('HH') || format.includes('H')) {
816
+ options.hour = format.includes('HH') ? '2-digit' : 'numeric';
817
+ options.hour12 = false;
818
+ }
819
+ else if (format.includes('hh') || format.includes('h')) {
820
+ options.hour = format.includes('hh') ? '2-digit' : 'numeric';
821
+ options.hour12 = true;
822
+ }
823
+ // Handle minute
824
+ if (format.includes('mm')) {
825
+ options.minute = '2-digit';
826
+ }
827
+ else if (format.includes('m')) {
828
+ options.minute = 'numeric';
829
+ }
830
+ // Handle second
831
+ if (format.includes('ss')) {
832
+ options.second = '2-digit';
833
+ }
834
+ else if (format.includes('s')) {
835
+ options.second = 'numeric';
836
+ }
837
+ // Handle AM/PM (overrides hour12 if explicitly set)
838
+ if (format.includes('A') || format.includes('a')) {
839
+ options.hour12 = true;
840
+ }
841
+ this.formatCache.set(cacheKey, { ...options });
842
+ return options;
843
+ }
844
+ convertAngularToMomentFormat(angularFormat) {
845
+ // Convert Angular DatePipe format to moment.js format
846
+ return angularFormat
847
+ .replace(/dd/g, 'DD') // Day of month: dd -> DD
848
+ .replace(/yyyy/g, 'YYYY') // Year: yyyy -> YYYY
849
+ .replace(/yy/g, 'YY') // Year: yy -> YY
850
+ .replace(/MM/g, 'MM') // Month: MM -> MM (same)
851
+ .replace(/M/g, 'M') // Month: M -> M (same)
852
+ .replace(/HH/g, 'HH') // Hour 24: HH -> HH (same)
853
+ .replace(/H/g, 'H') // Hour 24: H -> H (same)
854
+ .replace(/h/g, 'h') // Hour 12: h -> h (same)
855
+ .replace(/mm/g, 'mm') // Minute: mm -> mm (same)
856
+ .replace(/m/g, 'm') // Minute: m -> m (same)
857
+ .replace(/ss/g, 'ss') // Second: ss -> ss (same)
858
+ .replace(/s/g, 's') // Second: s -> s (same)
859
+ .replace(/a/g, 'a'); // AM/PM: a -> a (same)
860
+ }
861
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimezoneFormatPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
862
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: TimezoneFormatPipe, isStandalone: true, name: "timezoneFormat" }); }
863
+ }
864
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimezoneFormatPipe, decorators: [{
865
+ type: Pipe,
866
+ args: [{
867
+ name: 'timezoneFormat',
868
+ standalone: true
869
+ }]
870
+ }] });
871
+
719
872
  class BadgeOverflowComponent {
720
873
  constructor(elementRef, cdr) {
721
874
  this.elementRef = elementRef;
@@ -1024,7 +1177,12 @@ class TimeSheetComponent {
1024
1177
  // Insert spaces before capital letters (for camelCase)
1025
1178
  result = result.replace(/([a-z])([A-Z])/g, '$1 $2');
1026
1179
  // Capitalize first letter of each word
1027
- return result.replace(/\b\w/g, l => l.toUpperCase());
1180
+ result = result.replace(/\b\w/g, l => l.toUpperCase());
1181
+ // Special case for "Miss Punch Out" to become "Missed Punch Out"
1182
+ if (result === 'Miss Punch Out') {
1183
+ return 'Missed Punch Out';
1184
+ }
1185
+ return result;
1028
1186
  }
1029
1187
  constructor(injector, vcr, commonService) {
1030
1188
  // Constructor is now empty - dependencies injected above
@@ -1064,10 +1222,6 @@ class TimeSheetComponent {
1064
1222
  this.lastScrollTop = 0;
1065
1223
  this.scrollVelocity = 0;
1066
1224
  this.scrollAcceleration = 0;
1067
- // Infinite scroll optimizations
1068
- this.dataLoadQueue = [];
1069
- this.isLoadingData = false;
1070
- this.lastScrollPosition = 0;
1071
1225
  // Memory management
1072
1226
  this.componentRefs = new Set();
1073
1227
  this.eventListeners = new Map();
@@ -1224,11 +1378,6 @@ class TimeSheetComponent {
1224
1378
  this.progressiveLoadingChunks = [];
1225
1379
  this.progressiveLoadingIndex = 0;
1226
1380
  this.isProgressiveLoading = false;
1227
- // Infinite scroll inputs/outputs
1228
- this.enableInfiniteScroll = false;
1229
- this.hasMoreData = true;
1230
- this.loadingMore = false;
1231
- this.loadMoreData = new EventEmitter();
1232
1381
  // ///////////////////////////////////////////////////////////////////////////////////////////
1233
1382
  // ///////////////////////////////////////////////////////////////////////////////////////////
1234
1383
  // Out Put Events
@@ -1385,7 +1534,6 @@ class TimeSheetComponent {
1385
1534
  this.lastScrollTime = 0;
1386
1535
  this.previousVelocity = 0;
1387
1536
  this.previousScrollDirection = 'none';
1388
- this.isPrefetching = false;
1389
1537
  this.leftPinnedColumns = [];
1390
1538
  this.centerColumns = [];
1391
1539
  this.rightPinnedColumns = [];
@@ -1427,7 +1575,6 @@ class TimeSheetComponent {
1427
1575
  scrollTime: 0,
1428
1576
  filterTime: 0,
1429
1577
  sortTime: 0,
1430
- infiniteScrollTime: 0,
1431
1578
  lastRenderStart: 0,
1432
1579
  renderCount: 0
1433
1580
  };
@@ -1438,7 +1585,6 @@ class TimeSheetComponent {
1438
1585
  renderTime: 16.67, // 60fps
1439
1586
  scrollTime: 8.33, // 120fps for smooth scrolling
1440
1587
  filterTime: 100, // 100ms for acceptable filter response
1441
- infiniteScrollTime: 50, // 50ms for smooth infinite scroll
1442
1588
  };
1443
1589
  // Performance metrics interface
1444
1590
  this.metrics = {};
@@ -1645,7 +1791,7 @@ class TimeSheetComponent {
1645
1791
  };
1646
1792
  this.isActiveFilterOpen = false;
1647
1793
  this.activeSubButton = '';
1648
- this.pageSizeOptions = [5, 25, 50, 75, 100, 150, 200, 250, 300, 500];
1794
+ this.pageSizeOptions = [10, 25, 50, 75, 100, 150, 200, 250, 300, 500];
1649
1795
  this.searchTextForFilterDropDown = '';
1650
1796
  this.isFilterOpen = false;
1651
1797
  this.showFilters = this.showSideMenu ? false : false;
@@ -1901,7 +2047,7 @@ class TimeSheetComponent {
1901
2047
  // }
1902
2048
  async initializeLazyModules() {
1903
2049
  // Lazy load virtual scrolling module only when needed
1904
- if (this.enableInfiniteScroll || this.dataSet.length > 100) {
2050
+ if (this.dataSet.length > 100) {
1905
2051
  if (!VirtualScrollModule) {
1906
2052
  VirtualScrollModule = await import('@angular/cdk/scrolling');
1907
2053
  }
@@ -2026,8 +2172,6 @@ class TimeSheetComponent {
2026
2172
  // Use animation frame for smooth updates
2027
2173
  this.scheduleAnimationFrame(() => this.cdr.markForCheck());
2028
2174
  }
2029
- // Advanced infinite scroll with prefetching
2030
- this.handleAdvancedInfiniteScroll(scrollTop);
2031
2175
  // Force recalculation when accordion state changes
2032
2176
  if (this.hasAccordionStateChanged()) {
2033
2177
  this.updateVisibleRowsOptimized(scrollTop);
@@ -2095,68 +2239,6 @@ class TimeSheetComponent {
2095
2239
  }
2096
2240
  return translateY;
2097
2241
  }
2098
- handleAdvancedInfiniteScroll(scrollTop) {
2099
- if (!this.enableInfiniteScroll || this.isLoadingData || !this.hasMoreData)
2100
- return;
2101
- const el = this.mainScroll.nativeElement;
2102
- const viewportHeight = el.clientHeight;
2103
- const contentHeight = el.scrollHeight;
2104
- const scrollProgress = scrollTop / (contentHeight - viewportHeight);
2105
- // Dynamic thresholds based on scroll velocity
2106
- const velocityMultiplier = Math.min(Math.abs(this.scrollVelocity) * 50, 0.3);
2107
- const prefetchThreshold = Math.max(0.5, 0.7 - velocityMultiplier); // Earlier prefetch during fast scrolling
2108
- const loadThreshold = Math.max(0.8, 0.9 - velocityMultiplier); // Earlier loading during fast scrolling
2109
- if (scrollProgress >= loadThreshold) {
2110
- this.loadMoreDataOptimized();
2111
- }
2112
- else if (scrollProgress >= prefetchThreshold && !this.isPrefetching) {
2113
- this.prefetchData();
2114
- }
2115
- // Adaptive data windowing based on scroll position
2116
- this.adaptiveDataWindowing(scrollTop, contentHeight);
2117
- }
2118
- adaptiveDataWindowing(scrollTop, contentHeight) {
2119
- // Adjust data window size based on scroll position and velocity
2120
- const scrollProgress = scrollTop / contentHeight;
2121
- const velocity = Math.abs(this.scrollVelocity);
2122
- // Increase window size during fast scrolling near the end
2123
- if (scrollProgress > 0.8 && velocity > 2) {
2124
- this.maxRenderedItems = Math.min(200, this.maxRenderedItems + 50);
2125
- }
2126
- else if (scrollProgress < 0.2 && velocity < 1) {
2127
- // Reduce window size when scrolling slowly at the beginning
2128
- this.maxRenderedItems = Math.max(50, this.maxRenderedItems - 10);
2129
- }
2130
- }
2131
- prefetchData() {
2132
- if (this.isPrefetching)
2133
- return;
2134
- this.isPrefetching = true;
2135
- // Prefetch next batch in background
2136
- setTimeout(() => {
2137
- // Simulate prefetch logic - in real implementation, this would prepare data
2138
- this.isPrefetching = false;
2139
- }, 100);
2140
- }
2141
- prefetchNextBatch() {
2142
- if (this.isPrefetching || !this.hasMoreData)
2143
- return;
2144
- this.isPrefetching = true;
2145
- // Prepare data for next batch without triggering UI updates
2146
- // This could involve pre-calculating virtual indexes, caching computations, etc.
2147
- setTimeout(() => {
2148
- // Pre-compute next batch of data structures
2149
- const nextBatchSize = Math.min(100, this.paginationConfig?.limit || 50);
2150
- const startIndex = this.dataSet.length;
2151
- // Pre-allocate space in data structures
2152
- for (let i = 0; i < nextBatchSize; i++) {
2153
- const virtualIndex = startIndex + i + 1;
2154
- // Pre-compute any expensive calculations here
2155
- this.dataCache.set(`virtualIndex_${virtualIndex}`, { data: virtualIndex, timestamp: Date.now(), ttl: 30000 });
2156
- }
2157
- this.isPrefetching = false;
2158
- }, 50); // Small delay to avoid blocking main thread
2159
- }
2160
2242
  handleOptimizedFilter(filters) {
2161
2243
  this.startPerformanceTimer('filterTime');
2162
2244
  // Use worker for heavy filtering operations
@@ -2188,44 +2270,6 @@ class TimeSheetComponent {
2188
2270
  this.updateVisibleRowsOptimized(0);
2189
2271
  this.cdr.markForCheck();
2190
2272
  }
2191
- loadMoreDataOptimized() {
2192
- if (this.isLoadingData)
2193
- return;
2194
- this.isLoadingData = true;
2195
- this.startPerformanceTimer('infiniteScrollTime');
2196
- // Implement data windowing - keep only recent data in memory
2197
- this.optimizeDataWindow();
2198
- // Prefetch next batch in background for smoother experience
2199
- this.prefetchNextBatch();
2200
- this.loadMoreData.emit();
2201
- // Reset loading flag after a timeout to prevent rapid firing
2202
- const timeoutId = window.setTimeout(() => {
2203
- this.isLoadingData = false;
2204
- this.endPerformanceTimer('infiniteScrollTime');
2205
- }, 1000);
2206
- this.timeouts.add(timeoutId);
2207
- }
2208
- optimizeDataWindow() {
2209
- // Keep only a sliding window of data to prevent memory bloat
2210
- const maxWindowSize = 1000; // Keep max 1000 items in memory
2211
- const windowStart = Math.max(0, this.dataSet.length - maxWindowSize);
2212
- if (this.dataSet.length > maxWindowSize) {
2213
- // Remove old data from the beginning, but keep track of total count
2214
- this.dataSet.splice(0, this.dataSet.length - maxWindowSize);
2215
- this.originalDataSet.splice(0, this.originalDataSet.length - maxWindowSize);
2216
- // Adjust virtual indexes
2217
- this.dataSet.forEach((row, i) => {
2218
- row.__virtualIndex = windowStart + i + 1;
2219
- });
2220
- // Clear caches that might be affected
2221
- this.dynamicItemHeights.clear();
2222
- this.itemHeightCache.clear();
2223
- // Update visible rows to reflect new data window
2224
- this.updateVisibleRowsOptimized(0);
2225
- // Force viewport recalculation
2226
- this.computeViewportRows();
2227
- }
2228
- }
2229
2273
  async ngOnChanges(changes) {
2230
2274
  // Batch change detection updates
2231
2275
  let needsUpdate = false;
@@ -2266,9 +2310,6 @@ class TimeSheetComponent {
2266
2310
  else {
2267
2311
  this.processDataSetDirectly();
2268
2312
  }
2269
- if (this.enableInfiniteScroll && this.groupedColumns.length > 0) {
2270
- console.warn('Grouping with infinite scroll may not work as expected');
2271
- }
2272
2313
  needsUpdate = true;
2273
2314
  }
2274
2315
  if (changes['checkboxState']?.currentValue?.reset) {
@@ -3225,31 +3266,37 @@ class TimeSheetComponent {
3225
3266
  }
3226
3267
  return false;
3227
3268
  }
3228
- openThreeDotsMenu(event, child) {
3269
+ openThreeDotsMenu(event, child, keepOriginalPosition = false) {
3229
3270
  event.preventDefault();
3230
3271
  event.stopPropagation();
3231
3272
  this.isMenueHidden = true;
3232
3273
  this.activeCol = child;
3233
3274
  this.activeFilterCell = null;
3275
+ // Open filter menu if clicked on column header (not three-dots icon itself)
3276
+ const target = event.target;
3277
+ const isThreeDotsIcon = target.closest('.three-dots');
3278
+ if (!isThreeDotsIcon) {
3279
+ this.openFilteronThreeDotsClick(child); // This opens the filter menu
3280
+ }
3281
+ const menuWidth = 240; // same as CSS
3282
+ const containerWidth = this.dataGridContainer?.nativeElement?.offsetWidth || window.innerWidth;
3234
3283
  const clickX = event.clientX;
3235
- const screenWidth = window.innerWidth;
3236
- const menuWidth = 240; // your menu size
3237
3284
  requestAnimationFrame(() => {
3238
- const element = this.getCachedElement('.column-menu');
3239
- if (element) {
3240
- let leftPos = clickX;
3241
- // If menu overflows on right → open to the left
3242
- if (clickX + menuWidth > screenWidth) {
3243
- leftPos = clickX - menuWidth;
3244
- }
3245
- // If menu overflows on left → push to 0
3246
- if (leftPos < 0) {
3247
- leftPos = 0;
3248
- }
3249
- element.style.left = `${leftPos}px`;
3250
- }
3285
+ const element = document.querySelector('.column-menu');
3286
+ if (!element)
3287
+ return;
3288
+ let leftPos = clickX;
3289
+ // If menu overflows right move left
3290
+ if (clickX + menuWidth > containerWidth) {
3291
+ leftPos = containerWidth - menuWidth - 10; // 10px padding
3292
+ }
3293
+ // If menu overflows left → push to 0
3294
+ if (leftPos < 0)
3295
+ leftPos = 0;
3296
+ element.style.left = `${leftPos}px`;
3297
+ // Top position is handled by CSS or naturally by Angular position
3251
3298
  this.isMenueHidden = false;
3252
- this.cdr.markForCheck();
3299
+ this.cdr.detectChanges();
3253
3300
  });
3254
3301
  }
3255
3302
  // ////////////////////////////////////////////////////////////////////////////////////////
@@ -3672,8 +3719,8 @@ class TimeSheetComponent {
3672
3719
  clearFilter(col) {
3673
3720
  col.firstValue = '';
3674
3721
  col.secondValue = '';
3675
- col.firstCondition = 'contains';
3676
- col.secondCondition = 'contains';
3722
+ col.firstCondition = (col.type === 'date' || col.type === 'time') ? 'equal' : 'contain';
3723
+ col.secondCondition = (col.type === 'date' || col.type === 'time') ? 'equal' : 'contain';
3677
3724
  col.logic = 'AND';
3678
3725
  col.selectAll = false;
3679
3726
  col.selectedOptions = {};
@@ -4558,11 +4605,11 @@ class TimeSheetComponent {
4558
4605
  this.filterMenueSearchInput.nativeElement.focus();
4559
4606
  }, 100);
4560
4607
  }
4561
- else if (['string', 'number', 'date'].includes(col.type)) {
4562
- this.firstCondition = col?.query?.first_condition || 'contain';
4608
+ else if (['string', 'number', 'date', 'time'].includes(col.type)) {
4609
+ this.firstCondition = col?.query?.first_condition || ((col.type === 'date' || col.type === 'time') ? 'equal' : 'contain');
4563
4610
  this.firstValue = col?.query?.first_value || '';
4564
4611
  this.condition = col?.query?.condition || 'none';
4565
- this.secondCondition = col?.query?.second_condition || 'contain';
4612
+ this.secondCondition = col?.query?.second_condition || ((col.type === 'date' || col.type === 'time') ? 'equal' : 'contain');
4566
4613
  this.secondValue = col?.query?.second_value || '';
4567
4614
  setTimeout(() => {
4568
4615
  this.filterMenueTextchInput.nativeElement.focus();
@@ -4670,13 +4717,15 @@ class TimeSheetComponent {
4670
4717
  }
4671
4718
  });
4672
4719
  }
4673
- else if (['string', 'number', 'date'].includes(column.type)) {
4720
+ else if (['string', 'number', 'date', 'time'].includes(column.type)) {
4674
4721
  column.query = {
4675
- first_condition: this.firstCondition || 'contain',
4722
+ first_condition: this.firstCondition || ((column.type === 'date' || column.type === 'time') ? 'equal' : 'contain'),
4676
4723
  first_value: this.firstValue || null,
4677
4724
  condition: this.condition || 'none',
4678
- second_condition: this.secondCondition || null,
4679
- second_value: this.secondValue || null,
4725
+ ...(this.condition !== 'none' && {
4726
+ second_condition: this.secondCondition || ((column.type === 'date' || column.type === 'time') ? 'equal' : 'contain'),
4727
+ second_value: this.secondValue || null,
4728
+ }),
4680
4729
  };
4681
4730
  }
4682
4731
  }
@@ -4700,10 +4749,10 @@ class TimeSheetComponent {
4700
4749
  // Ensure default conditions are set before applying filter
4701
4750
  if (column.query) {
4702
4751
  if (!column.query.first_condition) {
4703
- column.query.first_condition = 'contain';
4752
+ column.query.first_condition = (column.type === 'date' || column.type === 'time') ? 'equal' : 'contain';
4704
4753
  }
4705
- if (!column.query.second_condition) {
4706
- column.query.second_condition = 'contain';
4754
+ if (!column.query.second_condition && column.query.condition !== 'none') {
4755
+ column.query.second_condition = (column.type === 'date' || column.type === 'time') ? 'equal' : 'contain';
4707
4756
  }
4708
4757
  }
4709
4758
  const filter = {
@@ -6818,16 +6867,41 @@ class TimeSheetComponent {
6818
6867
  row.details.data = row.details.originalData.filter((item) => {
6819
6868
  return Object.keys(filters).every(field => {
6820
6869
  const config = filters[field] || {};
6821
- const term = (config.value || '').toLowerCase();
6870
+ const term = config.value;
6822
6871
  if (!term)
6823
6872
  return true;
6824
- const value = String(this.getNestedValue(item, field) || '').toLowerCase();
6873
+ const rawValue = this.getNestedValue(item, field);
6825
6874
  const condition = config.condition || 'contain';
6826
- switch (condition) {
6827
- case 'equal': return value === term;
6828
- case 'start': return value.startsWith(term);
6829
- case 'end': return value.endsWith(term);
6830
- default: return value.includes(term);
6875
+ // Find the column to check its type
6876
+ const col = row.details.columns.find((c) => c.field === field);
6877
+ const isDateTime = col && (col.type === 'date' || col.type === 'time');
6878
+ if (isDateTime) {
6879
+ // Handle date/time comparisons
6880
+ const value = new Date(rawValue);
6881
+ const filterValue = new Date(term);
6882
+ if (isNaN(value.getTime()) || isNaN(filterValue.getTime()))
6883
+ return false;
6884
+ switch (condition) {
6885
+ case 'equal': return value.getTime() === filterValue.getTime();
6886
+ case 'not_equal': return value.getTime() !== filterValue.getTime();
6887
+ case 'after': return value.getTime() > filterValue.getTime();
6888
+ case 'before': return value.getTime() < filterValue.getTime();
6889
+ default: return false;
6890
+ }
6891
+ }
6892
+ else {
6893
+ // Handle text comparisons
6894
+ const value = String(rawValue || '').toLowerCase();
6895
+ const filterTerm = String(term).toLowerCase();
6896
+ switch (condition) {
6897
+ case 'equal': return value === filterTerm;
6898
+ case 'not_equal': return value !== filterTerm;
6899
+ case 'start': return value.startsWith(filterTerm);
6900
+ case 'end': return value.endsWith(filterTerm);
6901
+ case 'after': return value > filterTerm;
6902
+ case 'before': return value < filterTerm;
6903
+ default: return value.includes(filterTerm);
6904
+ }
6831
6905
  }
6832
6906
  });
6833
6907
  });
@@ -7748,7 +7822,7 @@ class TimeSheetComponent {
7748
7822
  }
7749
7823
  getEntriesForDate(date) {
7750
7824
  return this.dataSet.filter(row => {
7751
- const rowDate = new Date(row.attendanceDate);
7825
+ const rowDate = new Date(row.attendance_date);
7752
7826
  return rowDate.toDateString() === date.toDateString();
7753
7827
  });
7754
7828
  }
@@ -7876,7 +7950,7 @@ class TimeSheetComponent {
7876
7950
  }
7877
7951
  getActivityForDate(date) {
7878
7952
  const entries = this.dataSet.filter(row => {
7879
- const rowDate = new Date(row.attendanceDate);
7953
+ const rowDate = new Date(row.attendance_date);
7880
7954
  return rowDate.toDateString() === date.toDateString();
7881
7955
  });
7882
7956
  return entries.reduce((total, entry) => {
@@ -7924,11 +7998,10 @@ class TimeSheetComponent {
7924
7998
  // };
7925
7999
  // event.stopPropagation();
7926
8000
  // }
7927
- formatDate(date) {
7928
- if (!date)
7929
- return '';
7930
- return this.datePipe.transform(date, this.prefs.dateFormat, this.prefs.timeZone) || '';
7931
- }
8001
+ // formatDate(date: any): string {
8002
+ // if (!date) return '';
8003
+ // return this.datePipe.transform(date, this.prefs.dateFormat, this.prefs.timeZone) || '';
8004
+ // }
7932
8005
  getTimeValue(value) {
7933
8006
  if (!value || value === '-')
7934
8007
  return '';
@@ -7946,6 +8019,7 @@ class TimeSheetComponent {
7946
8019
  return value;
7947
8020
  }
7948
8021
  formatTime(value) {
8022
+ debugger;
7949
8023
  if (!value)
7950
8024
  return '-';
7951
8025
  value = this.getTimeValue(value); // normalize first
@@ -8000,7 +8074,7 @@ class TimeSheetComponent {
8000
8074
  }
8001
8075
  }
8002
8076
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimeSheetComponent, deps: [{ token: i0.Injector }, { token: i0.ViewContainerRef }, { token: CommonService }], target: i0.ɵɵFactoryTarget.Component }); }
8003
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeSheetComponent, isStandalone: true, selector: "time-sheet", inputs: { paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", enableExport: "enableExport", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", selectedPresetId: "selectedPresetId", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", isSingleDay: "isSingleDay", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", enableAccordionShadow: "enableAccordionShadow", enableAccordionSeparators: "enableAccordionSeparators", enableRowShading: "enableRowShading", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBAckgroundColor: "nestedTableHeaderBAckgroundColor", tableView: "tableView", columnThreedotsMunuConfig: "columnThreedotsMunuConfig", timezonePrefs: "timezonePrefs", enableProgressiveLoading: "enableProgressiveLoading", progressiveChunkSize: "progressiveChunkSize", progressiveDelay: "progressiveDelay", enableInfiniteScroll: "enableInfiniteScroll", hasMoreData: "hasMoreData", loadingMore: "loadingMore", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", buttons: "buttons", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", loadMoreData: "loadMoreData", changeLayout: "changeLayout", filterOptions: "filterOptions", filterCleared: "filterCleared", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing", loadMore: "loadMore", emailClicked: "emailClicked", addAttendanceClicked: "addAttendanceClicked", backPayClicked: "backPayClicked", grandTotalClicked: "grandTotalClicked", printClicked: "printClicked", exportClicked: "exportClicked", exportDailyClicked: "exportDailyClicked", deleteClicked: "deleteClicked" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape($event)", "window:resize": "onResize($event)", "document:keydown": "onKeyDown($event)", "document:paste": "onPaste($event)" } }, viewQueries: [{ propertyName: "cellText", first: true, predicate: ["cellText"], descendants: true }, { propertyName: "dataGridContainer", first: true, predicate: ["dataGridContainer"], descendants: true }, { propertyName: "leftPinnedBody", first: true, predicate: ["leftPinnedBody"], descendants: true }, { propertyName: "centerPinnedBody", first: true, predicate: ["centerPinnedBody"], descendants: true }, { propertyName: "rightPinnedBody", first: true, predicate: ["rightPinnedBody"], descendants: true }, { propertyName: "leftPinnedHeader", first: true, predicate: ["leftPinnedHeader"], descendants: true }, { propertyName: "centerPinnedHeader", first: true, predicate: ["centerPinnedHeader"], descendants: true }, { propertyName: "rightPinnedHeader", first: true, predicate: ["rightPinnedHeader"], descendants: true }, { propertyName: "columnsGroupedBox", first: true, predicate: ["columnsGroupedBox"], descendants: true }, { propertyName: "centerFakeScrollbar", first: true, predicate: ["centerFakeScrollbar"], descendants: true }, { propertyName: "centerScroll", first: true, predicate: ["centerScroll"], descendants: true }, { propertyName: "mainScroll", first: true, predicate: ["mainScroll"], descendants: true }, { propertyName: "fakeScroll", first: true, predicate: ["fakeScroll"], descendants: true }, { propertyName: "horizintalFakeScroll", first: true, predicate: ["horizintalFakeScroll"], descendants: true }, { propertyName: "centerScrollableBody", first: true, predicate: ["centerScrollableBody"], descendants: true }, { propertyName: "filterMenueSearchInput", first: true, predicate: ["filterMenueSearchInput"], descendants: true }, { propertyName: "filterMenueTextchInput", first: true, predicate: ["filterMenueTextchInput"], descendants: true }, { propertyName: "headerContainer", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "dataContainer", first: true, predicate: ["dataContainer"], descendants: true }, { propertyName: "leftContainer", first: true, predicate: ["leftContainer"], descendants: true }, { propertyName: "rightContainer", first: true, predicate: ["rightContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n\r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n\r\n <!-- Date Picker Buttons -->\r\n <!-- Date Picker Section - Improved Version -->\r\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\r\n\r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n\r\n <!-- Left Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('left')\"\r\n title=\"Previous Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-left\"></span>\r\n </span>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-primary date-range-label cursor-pointer\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Click to open calendar\"\r\n >\r\n {{ formatDate(bsRangeValue[0]) }} - {{ formatDate(bsRangeValue[1]) }}\r\n </span>\r\n\r\n <!-- Right Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('right')\"\r\n title=\"Next Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-right\"></span>\r\n </span>\r\n\r\n\r\n\r\n</div>\r\n\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <div class=\"action-buttons-row d-flex\">\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Select Date Range\"\r\n >\r\n <span class=\"bi bi-calendar3 text-primary\"></span>\r\n <span class=\"label-hidden text-white\">Calendar</span>\r\n </a>\r\n <button\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\r\n type=\"button\"\r\n class=\"button button-small btn btn-active-danger border border-danger me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date Range\"\r\n >\r\n <span class=\"bi bi-x-circle text-danger\"></span>\r\n <span class=\"label-hidden text-white\">Clear</span>\r\n </button>\r\n</div>\r\n<ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"action-buttons-row\"\r\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button\"\r\n [title]=\"button.name\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"button.iconPath\"\r\n class=\"svg-icon\"\r\n ></span>\r\n <span\r\n class=\"label-hidden\"\r\n >{{ button.name }}</span\r\n >\r\n </a>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Calendar Button -->\r\n\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Filters</span>\r\n </a>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 16px;\r\n top: 10px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer d-none\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer action-buttons-row\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n >\r\n <!-- <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span> -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Setting</span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n style=\"position: absolute\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"toggleOpenFilter(); activeTopButton = ''\"\r\n *ngIf=\"!showFilterRow\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('csv')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n CSV Export\r\n </a>\r\n <a\r\n *ngIf=\"enableExport\"\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('xlsx')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Excel Export\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div class=\"d-flex gap-2 align-items-center me-5\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n\r\n\r\n\r\n</div>\r\n<div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n>\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"65\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n ></div>\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterHeaderScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"openThreeDotsMenu($event, 'group')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"onResizeGroupBox($event)\"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <!-- <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'previewRightPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet.length && !loading\"\r\n >\r\n No Record Found\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n \r\n\r\n <!-- Table View -->\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length) + (hasMoreData ? 1000 : 0)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onHorizintalFakeScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.selectedPageSize\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, child)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"onResizeColumn($event, child)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div class=\"group-column-wrapper\">\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"onResizeColumn($event, col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"65\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"65\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n </div>\r\n <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4 border-right\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"circle-value badge-outline break-on text-center\"\r\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' ? 'break-color-paid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' ? 'break-color-unpaid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n \r\n >\r\n -\r\n</div>\r\n</ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveDetail>\r\n <div >-</div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Status -->\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (mouseenter)=\"showManualLogsTooltip($event, row, d)\" (mouseleave)=\"hideManualLogsTooltip()\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? formatDate(getNestedValue(d, col.field)) : '-')\r\n : col.type === 'time'\r\n ? formatTime(getTimeValue(getNestedValue(d, col.field)))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"rowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div>\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col.type === 'date'\r\n ? (getNestedValue(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [ngClass]=\"(row.short_breaks.type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (row.short_breaks.type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (row.short_breaks.type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Payroll Processed -->\r\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Restriction -->\r\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? formatDate(getNestedValue(row, col.field))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : col.type === 'time'\r\n ? formatTime(getTimeValue(getNestedValue(row, col.field)))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\r\n\r\n <!-- <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span> -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n In: {{ formatTime(getTimeValue(currentBreakTooltip.break_in_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ formatTime(getTimeValue(currentBreakTooltip.break_out_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentBreakTooltip.break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n Start: {{ formatTime(getTimeValue(currentShortBreakTooltip.start_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ formatTime(getTimeValue(currentShortBreakTooltip.end_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentShortBreakTooltip.short_break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <!-- <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div> -->\r\n\r\n <!-- Reset Columns -->\r\n <!-- <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div> -->\r\n </div>\r\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" [class.visually-hidden]=\"isMenueHidden\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col.query.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container >\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n</div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeModalColumnPanel()\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation();\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none btn btn-link\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save Preset\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div class=\"\" (click)=\"selectDefault()\">\r\n <div class=\"fw-semibold\">Default View\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\"\r\n >Created {{ formatDate(table?.createdAt) }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\r\n >Update</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\r\n >\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"show_hide_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Show All</label>\r\n </div> -->\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length && !isMandatory(col)\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"(!col?.query?.first_value && !col?.query?._ids?.length && isMandatory(col)) || (col?.query?.first_value || col?.query?._ids?.length)\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <!-- <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Hide All</label>\r\n </div> -->\r\n\r\n \r\n\r\n\r\n\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"firstValue && condition !== 'none'\">\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n [(ngModel)]=\"secondValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{ item?.department_name || item?.roleName || \"-\" }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n (mouseleave)=\"closeManualLogsModal()\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? formatDate(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? formatTime(getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'badge-success' : 'badge-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"popover__wrapper\" >none\r\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div> -->\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\r\n>\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Short Leave Tooltip Modal -->\r\n<div *ngIf=\"showShortLeaveTooltipModal\" \r\n class=\"custom-break-tooltips\" \r\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\" \r\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\r\n (mouseenter)=\"preventShortLeaveTooltipHide()\" \r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Leave Type</th>\r\n <th>Start Time</th>\r\n <th>End Time</th>\r\n <th>Duration (min)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentShortLeaveData\">\r\n <td>{{ item.leave_type || 'N/A' }}</td>\r\n <td>{{ item.star_time || 'N/A' }}</td>\r\n <td>{{ item.end_time || 'N/A' }}</td>\r\n <td>{{ item.minutes || 'N/A' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Tooltip for accordion manual logs -->\r\n<!-- Tooltip for accordion manual logs -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous</th>\r\n <th>Updated</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date && item.log_date !== '--' ? formatDate(item.log_date) : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow.attendanceDate !== '--' ? formatDate(selectedManualLogsRow.attendanceDate) : '-') }}</td>\r\n <td>{{ formatLogState(item?.log_details?.previous_state) }}</td>\r\n <td>{{ formatLogState(item?.log_details?.updated_state) }}</td>\r\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\r\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Fallback for empty manual logs -->\r\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\r\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n<!-- </div> -->\r\n\r\n<ng-template #detailModalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:30px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#f6f8ff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:-15px;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:6px;display:flex;justify-content:center;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);margin-right:8px;transform:translateZ(0);position:relative}.chevron-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.chevron-wrapper:hover{background-color:#007bff1a;transform:scale(1.1)}.chevron-wrapper:hover:before{width:36px;height:36px}.chevron-wrapper:hover i{transform:scale(1.2);transition:transform .25s cubic-bezier(.4,0,.2,1)}.chevron-wrapper:active{transform:scale(.95);transition-duration:.15s}.chevron-wrapper i{font-size:14px;transition:transform .25s cubic-bezier(.4,0,.2,1)}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:6px}.columns-button:hover{background-color:#007bff1a;transform:scale(1.05)}.columns-button:active{transform:scale(.95)}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default;animation:slideInRight .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:8px;box-shadow:0 8px 32px #0000001f;backdrop-filter:blur(8px)}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.action-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px #007cf54d}.action-button:active{transform:translateY(0);transition-duration:.15s}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.global-search input:focus{outline:none!important;box-shadow:0 0 0 3px #007bff1a!important;border-color:#007bff!important;transform:scale(1.02)}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px}.custom-menu .dropdown-item:hover{background-color:#f5f5f5;border-radius:6px}.table-layout{right:0}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.page-buttons button:hover:not(:disabled){background-color:#007bff1a;border-color:#007bff;transform:translateY(-1px)}.page-buttons button:active:not(:disabled){transform:translateY(0) scale(.98)}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0!important}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0!important}.text-filter input:focus,.text-filter select:focus{box-shadow:none!important}.active-filters{background-color:#f7f7f7;white-space:nowrap;background:#f7f7f7;padding-inline:8px;height:28px;font-size:14px;font-weight:500;border-radius:8px;box-shadow:none}.active-filters .header-tag{white-space:nowrap}.filter-tags .active{background-color:#e6f2ff}.filter-tags .active .header-tag{color:#007cf5!important}.table-cell{cursor:pointer;width:100%}.table-cell input:focus{outline:0!important;border:0!important;width:100%!important;box-shadow:none!important}.active-for-editing{outline:2.5px solid #007cf5!important;border-radius:4px;border:0!important;width:100%!important}.active-cell{outline:none!important;box-shadow:inset 0 0 0 1.5px #007cf5}span[inlineSVG]{width:16px;height:16px;display:inline-block}.cell .dropdown-menu{min-width:unset!important}.cell .dropdown-menu .item{transition:background-color .3s ease;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.cell .dropdown-menu .item:hover{background-color:#f0f8ff}.cell .cell-editin-dropdown{scrollbar-width:thin!important;-webkit-user-select:none;user-select:none}.fw-semibold{font-weight:500!important}:host ::ng-deep .three-dots-col-menu svg,:host ::ng-deep .three-dots-col-menu svg path{stroke:#000!important}.fs-7{font-size:12px!important}.fs-8{font-size:10px!important}.all-filters-reset-button:hover{opacity:.7}.full-text-box{background:#fff;position:relative;display:flex;align-items:center;justify-content:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026}.full-text-content{border-radius:8px;max-width:600px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{letter-spacing:.5px}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#000;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i2.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i4.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: FilterPipe, name: "filter" }, { kind: "pipe", type: PinnedColumnsPipe, name: "pinnedColumns" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i5.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i5.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i6.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i6.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i7.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i7.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i7.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: BadgeOverflowComponent, selector: "app-badge-overflow", inputs: ["badges", "maxWidth"], outputs: ["badgeMouseEnter", "badgeMouseLeave", "overflowCountClick"] }], animations: [
8077
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TimeSheetComponent, isStandalone: true, selector: "time-sheet", inputs: { paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", enableExport: "enableExport", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", selectedPresetId: "selectedPresetId", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", isSingleDay: "isSingleDay", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", enableAccordionShadow: "enableAccordionShadow", enableAccordionSeparators: "enableAccordionSeparators", enableRowShading: "enableRowShading", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBAckgroundColor: "nestedTableHeaderBAckgroundColor", tableView: "tableView", columnThreedotsMunuConfig: "columnThreedotsMunuConfig", timezonePrefs: "timezonePrefs", enableProgressiveLoading: "enableProgressiveLoading", progressiveChunkSize: "progressiveChunkSize", progressiveDelay: "progressiveDelay", detailsIconPosition: "detailsIconPosition", detailsPosition: "detailsPosition", buttons: "buttons", isStartDateNotEqualToEndDate: "isStartDateNotEqualToEndDate" }, outputs: { onShortBreakClick: "onShortBreakClick", searchEvent: "searchEvent", changeLayout: "changeLayout", filterOptions: "filterOptions", filterCleared: "filterCleared", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing", loadMore: "loadMore", emailClicked: "emailClicked", addAttendanceClicked: "addAttendanceClicked", backPayClicked: "backPayClicked", grandTotalClicked: "grandTotalClicked", printClicked: "printClicked", exportClicked: "exportClicked", exportDailyClicked: "exportDailyClicked", deleteClicked: "deleteClicked" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape($event)", "window:resize": "onResize($event)", "document:keydown": "onKeyDown($event)", "document:paste": "onPaste($event)" } }, viewQueries: [{ propertyName: "cellText", first: true, predicate: ["cellText"], descendants: true }, { propertyName: "dataGridContainer", first: true, predicate: ["dataGridContainer"], descendants: true }, { propertyName: "leftPinnedBody", first: true, predicate: ["leftPinnedBody"], descendants: true }, { propertyName: "centerPinnedBody", first: true, predicate: ["centerPinnedBody"], descendants: true }, { propertyName: "rightPinnedBody", first: true, predicate: ["rightPinnedBody"], descendants: true }, { propertyName: "leftPinnedHeader", first: true, predicate: ["leftPinnedHeader"], descendants: true }, { propertyName: "centerPinnedHeader", first: true, predicate: ["centerPinnedHeader"], descendants: true }, { propertyName: "rightPinnedHeader", first: true, predicate: ["rightPinnedHeader"], descendants: true }, { propertyName: "columnsGroupedBox", first: true, predicate: ["columnsGroupedBox"], descendants: true }, { propertyName: "centerFakeScrollbar", first: true, predicate: ["centerFakeScrollbar"], descendants: true }, { propertyName: "centerScroll", first: true, predicate: ["centerScroll"], descendants: true }, { propertyName: "mainScroll", first: true, predicate: ["mainScroll"], descendants: true }, { propertyName: "fakeScroll", first: true, predicate: ["fakeScroll"], descendants: true }, { propertyName: "horizintalFakeScroll", first: true, predicate: ["horizintalFakeScroll"], descendants: true }, { propertyName: "centerScrollableBody", first: true, predicate: ["centerScrollableBody"], descendants: true }, { propertyName: "filterMenueSearchInput", first: true, predicate: ["filterMenueSearchInput"], descendants: true }, { propertyName: "filterMenueTextchInput", first: true, predicate: ["filterMenueTextchInput"], descendants: true }, { propertyName: "headerContainer", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "dataContainer", first: true, predicate: ["dataContainer"], descendants: true }, { propertyName: "leftContainer", first: true, predicate: ["leftContainer"], descendants: true }, { propertyName: "rightContainer", first: true, predicate: ["rightContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n\r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n\r\n <!-- Date Picker Buttons -->\r\n <!-- Date Picker Section - Improved Version -->\r\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\r\n\r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n\r\n <!-- Left Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('left')\"\r\n title=\"Previous Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-left\"></span>\r\n </span>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-primary date-range-label cursor-pointer\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Click to open calendar\"\r\n >\r\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\r\n </span>\r\n\r\n <!-- Right Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('right')\"\r\n title=\"Next Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-right\"></span>\r\n </span>\r\n\r\n\r\n\r\n</div>\r\n\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <div class=\"action-buttons-row d-flex\">\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Select Date Range\"\r\n >\r\n <span class=\"bi bi-calendar3 text-primary\"></span>\r\n <span class=\"label-hidden text-white\">Calendar</span>\r\n </a>\r\n <button\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\r\n type=\"button\"\r\n class=\"button button-small btn btn-active-danger border border-danger me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date Range\"\r\n >\r\n <span class=\"bi bi-x-circle text-danger\"></span>\r\n <span class=\"label-hidden text-white\">Clear</span>\r\n </button>\r\n</div>\r\n<ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"action-buttons-row\"\r\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button\"\r\n [title]=\"button.name\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"button.iconPath\"\r\n class=\"svg-icon\"\r\n ></span>\r\n <span\r\n class=\"label-hidden\"\r\n >{{ button.name }}</span\r\n >\r\n </a>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Calendar Button -->\r\n\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Filters</span>\r\n </a>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 16px;\r\n top: 10px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer d-none\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer action-buttons-row\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n >\r\n <!-- <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span> -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Setting</span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n style=\"position: absolute\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"toggleOpenFilter(); activeTopButton = ''\"\r\n *ngIf=\"!showFilterRow\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('csv')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n CSV Export\r\n </a>\r\n <a\r\n *ngIf=\"enableExport\"\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('xlsx')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Excel Export\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div class=\"d-flex gap-2 align-items-center me-5\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n\r\n\r\n\r\n</div>\r\n<div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n>\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"65\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n S.No</div>\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterHeaderScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"openThreeDotsMenu($event, 'group')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"onResizeGroupBox($event)\"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <!-- <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'previewRightPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet.length && !loading\"\r\n >\r\n No Record Found\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n \r\n\r\n <!-- Table View -->\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onHorizintalFakeScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.selectedPageSize\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, child)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"onResizeColumn($event, child)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div class=\"group-column-wrapper\">\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"onResizeColumn($event, col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"65\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"65\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n </div>\r\n <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4 border-right\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"circle-value badge-outline break-on text-center\"\r\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' ? 'break-color-paid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' ? 'break-color-unpaid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n \r\n >\r\n -\r\n</div>\r\n</ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveDetail>\r\n <div >-</div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Status -->\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (mouseenter)=\"showManualLogsTooltip($event, row, d)\" (mouseleave)=\"hideManualLogsTooltip()\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"rowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div>\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col.type === 'date'\r\n ? (getNestedValue(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [ngClass]=\"(row.short_breaks.type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (row.short_breaks.type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (row.short_breaks.type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Payroll Processed -->\r\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Restriction -->\r\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\r\n\r\n <!-- <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span> -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n In: {{ getTimeValue(currentBreakTooltip.break_in_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ getTimeValue(currentBreakTooltip.break_out_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentBreakTooltip.break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n Start: {{ getTimeValue(currentShortBreakTooltip.start_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ getTimeValue(currentShortBreakTooltip.end_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentShortBreakTooltip.short_break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping && !(col.is_groupable === false)\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <!-- <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div> -->\r\n\r\n <!-- Reset Columns -->\r\n <!-- <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div> -->\r\n </div>\r\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col.query.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container >\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n</div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeModalColumnPanel()\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation();\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none btn btn-link\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save Preset\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div class=\"\" (click)=\"selectDefault()\">\r\n <div class=\"fw-semibold\">Default View\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\"\r\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\r\n >Update</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\r\n >\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"show_hide_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Show All</label>\r\n </div> -->\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length && !isMandatory(col)\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"(!col?.query?.first_value && !col?.query?._ids?.length && isMandatory(col)) || (col?.query?.first_value || col?.query?._ids?.length)\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <!-- <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Hide All</label>\r\n </div> -->\r\n\r\n \r\n\r\n\r\n\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptions>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"firstValue && condition !== 'none'\">\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptionsSecond>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n [(ngModel)]=\"secondValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{ item?.department_name || item?.roleName || \"-\" }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n (mouseleave)=\"closeManualLogsModal()\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'badge-success' : 'badge-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"popover__wrapper\" >none\r\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div> -->\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\r\n>\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Short Leave Tooltip Modal -->\r\n<div *ngIf=\"showShortLeaveTooltipModal\" \r\n class=\"custom-break-tooltips\" \r\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\" \r\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\r\n (mouseenter)=\"preventShortLeaveTooltipHide()\" \r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Leave Type</th>\r\n <th>Start Time</th>\r\n <th>End Time</th>\r\n <th>Duration (min)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentShortLeaveData\">\r\n <td>{{ item.leave_type || 'N/A' }}</td>\r\n <td>{{ item.star_time || 'N/A' }}</td>\r\n <td>{{ item.end_time || 'N/A' }}</td>\r\n <td>{{ item.minutes || 'N/A' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Tooltip for accordion manual logs -->\r\n<!-- Tooltip for accordion manual logs -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous</th>\r\n <th>Updated</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'date') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'date') : '-') }}</td>\r\n <td>{{ formatLogState(item?.log_details?.previous_state) }}</td>\r\n <td>{{ formatLogState(item?.log_details?.updated_state) }}</td>\r\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\r\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Fallback for empty manual logs -->\r\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\r\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n<!-- </div> -->\r\n\r\n<ng-template #detailModalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:30px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#f6f8ff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:-15px;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:6px;display:flex;justify-content:center;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);margin-right:8px;transform:translateZ(0);position:relative}.chevron-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.chevron-wrapper:hover{background-color:#007bff1a;transform:scale(1.1)}.chevron-wrapper:hover:before{width:36px;height:36px}.chevron-wrapper:hover i{transform:scale(1.2);transition:transform .25s cubic-bezier(.4,0,.2,1)}.chevron-wrapper:active{transform:scale(.95);transition-duration:.15s}.chevron-wrapper i{font-size:14px;transition:transform .25s cubic-bezier(.4,0,.2,1)}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:6px}.columns-button:hover{background-color:#007bff1a;transform:scale(1.05)}.columns-button:active{transform:scale(.95)}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default;animation:slideInRight .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:8px;box-shadow:0 8px 32px #0000001f;backdrop-filter:blur(8px)}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.action-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px #007cf54d}.action-button:active{transform:translateY(0);transition-duration:.15s}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.global-search input:focus{outline:none!important;box-shadow:0 0 0 3px #007bff1a!important;border-color:#007bff!important;transform:scale(1.02)}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px}.custom-menu .dropdown-item:hover{background-color:#f5f5f5;border-radius:6px}.table-layout{right:0}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.page-buttons button:hover:not(:disabled){background-color:#007bff1a;border-color:#007bff;transform:translateY(-1px)}.page-buttons button:active:not(:disabled){transform:translateY(0) scale(.98)}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0!important}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0!important}.text-filter input:focus,.text-filter select:focus{box-shadow:none!important}.active-filters{background-color:#f7f7f7;white-space:nowrap;background:#f7f7f7;padding-inline:8px;height:28px;font-size:14px;font-weight:500;border-radius:8px;box-shadow:none}.active-filters .header-tag{white-space:nowrap}.filter-tags .active{background-color:#e6f2ff}.filter-tags .active .header-tag{color:#007cf5!important}.table-cell{cursor:pointer;width:100%}.table-cell input:focus{outline:0!important;border:0!important;width:100%!important;box-shadow:none!important}.active-for-editing{outline:2.5px solid #007cf5!important;border-radius:4px;border:0!important;width:100%!important}.active-cell{outline:none!important;box-shadow:inset 0 0 0 1.5px #007cf5}span[inlineSVG]{width:16px;height:16px;display:inline-block}.cell .dropdown-menu{min-width:unset!important}.cell .dropdown-menu .item{transition:background-color .3s ease;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.cell .dropdown-menu .item:hover{background-color:#f0f8ff}.cell .cell-editin-dropdown{scrollbar-width:thin!important;-webkit-user-select:none;user-select:none}.fw-semibold{font-weight:500!important}:host ::ng-deep .three-dots-col-menu svg,:host ::ng-deep .three-dots-col-menu svg path{stroke:#000!important}.fs-7{font-size:12px!important}.fs-8{font-size:10px!important}.all-filters-reset-button:hover{opacity:.7}.full-text-box{background:#fff;position:relative;display:flex;align-items:center;justify-content:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026}.full-text-content{border-radius:8px;max-width:600px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{letter-spacing:.5px}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#000;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i2.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InlineSVGModule }, { kind: "directive", type: i4.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "pipe", type: FilterPipe, name: "filter" }, { kind: "pipe", type: PinnedColumnsPipe, name: "pinnedColumns" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i5.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i5.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i5.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i5.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i5.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i6.BsDaterangepickerDirective, selector: "[bsDaterangepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isOpen", "bsValue", "bsConfig", "isDisabled", "minDate", "maxDate", "dateCustomClasses", "daysDisabled", "datesDisabled", "datesEnabled"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDaterangepicker"] }, { kind: "directive", type: i6.BsDaterangepickerInputDirective, selector: "input[bsDaterangepicker]" }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i7.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i7.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i7.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: BadgeOverflowComponent, selector: "app-badge-overflow", inputs: ["badges", "maxWidth"], outputs: ["badgeMouseEnter", "badgeMouseLeave", "overflowCountClick"] }, { kind: "pipe", type: TimezoneFormatPipe, name: "timezoneFormat" }], animations: [
8004
8078
  trigger('accordionToggle', [
8005
8079
  state('collapsed', style({ height: '0px', overflow: 'hidden' })),
8006
8080
  state('expanded', style({ height: '*', overflow: 'visible' })),
@@ -8026,7 +8100,7 @@ class TimeSheetComponent {
8026
8100
  }
8027
8101
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TimeSheetComponent, decorators: [{
8028
8102
  type: Component,
8029
- args: [{ selector: 'time-sheet', standalone: true, imports: [CommonModule, FormsModule, InlineSVGModule, FilterPipe, PinnedColumnsPipe, DragDropModule, BsDatepickerModule, ScrollingModule, BadgeOverflowComponent, DatePipe,], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
8103
+ args: [{ selector: 'time-sheet', standalone: true, imports: [CommonModule, FormsModule, InlineSVGModule, FilterPipe, PinnedColumnsPipe, DragDropModule, BsDatepickerModule, ScrollingModule, BadgeOverflowComponent, DatePipe, TimezoneFormatPipe], changeDetection: ChangeDetectionStrategy.OnPush, animations: [
8030
8104
  trigger('accordionToggle', [
8031
8105
  state('collapsed', style({ height: '0px', overflow: 'hidden' })),
8032
8106
  state('expanded', style({ height: '*', overflow: 'visible' })),
@@ -8048,7 +8122,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8048
8122
  transition('void => *', animate('300ms ease-out')),
8049
8123
  transition('* => void', animate('300ms ease-in')),
8050
8124
  ])
8051
- ], template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n\r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n\r\n <!-- Date Picker Buttons -->\r\n <!-- Date Picker Section - Improved Version -->\r\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\r\n\r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n\r\n <!-- Left Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('left')\"\r\n title=\"Previous Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-left\"></span>\r\n </span>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-primary date-range-label cursor-pointer\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Click to open calendar\"\r\n >\r\n {{ formatDate(bsRangeValue[0]) }} - {{ formatDate(bsRangeValue[1]) }}\r\n </span>\r\n\r\n <!-- Right Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('right')\"\r\n title=\"Next Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-right\"></span>\r\n </span>\r\n\r\n\r\n\r\n</div>\r\n\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <div class=\"action-buttons-row d-flex\">\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Select Date Range\"\r\n >\r\n <span class=\"bi bi-calendar3 text-primary\"></span>\r\n <span class=\"label-hidden text-white\">Calendar</span>\r\n </a>\r\n <button\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\r\n type=\"button\"\r\n class=\"button button-small btn btn-active-danger border border-danger me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date Range\"\r\n >\r\n <span class=\"bi bi-x-circle text-danger\"></span>\r\n <span class=\"label-hidden text-white\">Clear</span>\r\n </button>\r\n</div>\r\n<ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"action-buttons-row\"\r\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button\"\r\n [title]=\"button.name\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"button.iconPath\"\r\n class=\"svg-icon\"\r\n ></span>\r\n <span\r\n class=\"label-hidden\"\r\n >{{ button.name }}</span\r\n >\r\n </a>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Calendar Button -->\r\n\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Filters</span>\r\n </a>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 16px;\r\n top: 10px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer d-none\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer action-buttons-row\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n >\r\n <!-- <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span> -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Setting</span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n style=\"position: absolute\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"toggleOpenFilter(); activeTopButton = ''\"\r\n *ngIf=\"!showFilterRow\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('csv')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n CSV Export\r\n </a>\r\n <a\r\n *ngIf=\"enableExport\"\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('xlsx')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Excel Export\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div class=\"d-flex gap-2 align-items-center me-5\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n\r\n\r\n\r\n</div>\r\n<div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n>\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"65\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n ></div>\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterHeaderScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"openThreeDotsMenu($event, 'group')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"onResizeGroupBox($event)\"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <!-- <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'previewRightPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet.length && !loading\"\r\n >\r\n No Record Found\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div *ngIf=\"loadingMore && enableInfiniteScroll\" class=\"text-center p-2\" [style.height.px]=\"rowHeight\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading more...\r\n</div>\r\n <div *ngIf=\"!(loadingMore && enableInfiniteScroll)\" class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n \r\n\r\n <!-- Table View -->\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length) + (hasMoreData ? 1000 : 0)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onHorizintalFakeScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.selectedPageSize\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, child)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"onResizeColumn($event, child)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div class=\"group-column-wrapper\">\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"onResizeColumn($event, col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"65\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"65\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n </div>\r\n <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4 border-right\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"circle-value badge-outline break-on text-center\"\r\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' ? 'break-color-paid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' ? 'break-color-unpaid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n \r\n >\r\n -\r\n</div>\r\n</ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveDetail>\r\n <div >-</div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Status -->\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (mouseenter)=\"showManualLogsTooltip($event, row, d)\" (mouseleave)=\"hideManualLogsTooltip()\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? formatDate(getNestedValue(d, col.field)) : '-')\r\n : col.type === 'time'\r\n ? formatTime(getTimeValue(getNestedValue(d, col.field)))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"rowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div>\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col.type === 'date'\r\n ? (getNestedValue(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [ngClass]=\"(row.short_breaks.type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (row.short_breaks.type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (row.short_breaks.type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Payroll Processed -->\r\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Restriction -->\r\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? formatDate(getNestedValue(row, col.field))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : col.type === 'time'\r\n ? formatTime(getTimeValue(getNestedValue(row, col.field)))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\r\n\r\n <!-- <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span> -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n In: {{ formatTime(getTimeValue(currentBreakTooltip.break_in_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ formatTime(getTimeValue(currentBreakTooltip.break_out_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentBreakTooltip.break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n Start: {{ formatTime(getTimeValue(currentShortBreakTooltip.start_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ formatTime(getTimeValue(currentShortBreakTooltip.end_time)) }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentShortBreakTooltip.short_break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <!-- <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div> -->\r\n\r\n <!-- Reset Columns -->\r\n <!-- <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div> -->\r\n </div>\r\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" [class.visually-hidden]=\"isMenueHidden\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col.query.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container >\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n</div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query.second_condition || 'contain'\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeModalColumnPanel()\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation();\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none btn btn-link\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save Preset\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div class=\"\" (click)=\"selectDefault()\">\r\n <div class=\"fw-semibold\">Default View\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\"\r\n >Created {{ formatDate(table?.createdAt) }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\r\n >Update</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\r\n >\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"show_hide_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Show All</label>\r\n </div> -->\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length && !isMandatory(col)\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"(!col?.query?.first_value && !col?.query?._ids?.length && isMandatory(col)) || (col?.query?.first_value || col?.query?._ids?.length)\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <!-- <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Hide All</label>\r\n </div> -->\r\n\r\n \r\n\r\n\r\n\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"firstValue && condition !== 'none'\">\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n [(ngModel)]=\"secondValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{ item?.department_name || item?.roleName || \"-\" }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n (mouseleave)=\"closeManualLogsModal()\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? formatDate(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? formatTime(getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'badge-success' : 'badge-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"popover__wrapper\" >none\r\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div> -->\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\r\n>\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Short Leave Tooltip Modal -->\r\n<div *ngIf=\"showShortLeaveTooltipModal\" \r\n class=\"custom-break-tooltips\" \r\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\" \r\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\r\n (mouseenter)=\"preventShortLeaveTooltipHide()\" \r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Leave Type</th>\r\n <th>Start Time</th>\r\n <th>End Time</th>\r\n <th>Duration (min)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentShortLeaveData\">\r\n <td>{{ item.leave_type || 'N/A' }}</td>\r\n <td>{{ item.star_time || 'N/A' }}</td>\r\n <td>{{ item.end_time || 'N/A' }}</td>\r\n <td>{{ item.minutes || 'N/A' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Tooltip for accordion manual logs -->\r\n<!-- Tooltip for accordion manual logs -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous</th>\r\n <th>Updated</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date && item.log_date !== '--' ? formatDate(item.log_date) : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow.attendanceDate !== '--' ? formatDate(selectedManualLogsRow.attendanceDate) : '-') }}</td>\r\n <td>{{ formatLogState(item?.log_details?.previous_state) }}</td>\r\n <td>{{ formatLogState(item?.log_details?.updated_state) }}</td>\r\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\r\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Fallback for empty manual logs -->\r\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\r\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n<!-- </div> -->\r\n\r\n<ng-template #detailModalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:30px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#f6f8ff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:-15px;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:6px;display:flex;justify-content:center;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);margin-right:8px;transform:translateZ(0);position:relative}.chevron-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.chevron-wrapper:hover{background-color:#007bff1a;transform:scale(1.1)}.chevron-wrapper:hover:before{width:36px;height:36px}.chevron-wrapper:hover i{transform:scale(1.2);transition:transform .25s cubic-bezier(.4,0,.2,1)}.chevron-wrapper:active{transform:scale(.95);transition-duration:.15s}.chevron-wrapper i{font-size:14px;transition:transform .25s cubic-bezier(.4,0,.2,1)}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:6px}.columns-button:hover{background-color:#007bff1a;transform:scale(1.05)}.columns-button:active{transform:scale(.95)}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default;animation:slideInRight .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:8px;box-shadow:0 8px 32px #0000001f;backdrop-filter:blur(8px)}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.action-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px #007cf54d}.action-button:active{transform:translateY(0);transition-duration:.15s}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.global-search input:focus{outline:none!important;box-shadow:0 0 0 3px #007bff1a!important;border-color:#007bff!important;transform:scale(1.02)}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px}.custom-menu .dropdown-item:hover{background-color:#f5f5f5;border-radius:6px}.table-layout{right:0}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.page-buttons button:hover:not(:disabled){background-color:#007bff1a;border-color:#007bff;transform:translateY(-1px)}.page-buttons button:active:not(:disabled){transform:translateY(0) scale(.98)}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0!important}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0!important}.text-filter input:focus,.text-filter select:focus{box-shadow:none!important}.active-filters{background-color:#f7f7f7;white-space:nowrap;background:#f7f7f7;padding-inline:8px;height:28px;font-size:14px;font-weight:500;border-radius:8px;box-shadow:none}.active-filters .header-tag{white-space:nowrap}.filter-tags .active{background-color:#e6f2ff}.filter-tags .active .header-tag{color:#007cf5!important}.table-cell{cursor:pointer;width:100%}.table-cell input:focus{outline:0!important;border:0!important;width:100%!important;box-shadow:none!important}.active-for-editing{outline:2.5px solid #007cf5!important;border-radius:4px;border:0!important;width:100%!important}.active-cell{outline:none!important;box-shadow:inset 0 0 0 1.5px #007cf5}span[inlineSVG]{width:16px;height:16px;display:inline-block}.cell .dropdown-menu{min-width:unset!important}.cell .dropdown-menu .item{transition:background-color .3s ease;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.cell .dropdown-menu .item:hover{background-color:#f0f8ff}.cell .cell-editin-dropdown{scrollbar-width:thin!important;-webkit-user-select:none;user-select:none}.fw-semibold{font-weight:500!important}:host ::ng-deep .three-dots-col-menu svg,:host ::ng-deep .three-dots-col-menu svg path{stroke:#000!important}.fs-7{font-size:12px!important}.fs-8{font-size:10px!important}.all-filters-reset-button:hover{opacity:.7}.full-text-box{background:#fff;position:relative;display:flex;align-items:center;justify-content:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026}.full-text-content{border-radius:8px;max-width:600px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{letter-spacing:.5px}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#000;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}\n"] }]
8125
+ ], template: "<div class=\"position-relative h-100\">\r\n <!-- <h1>abu </h1> -->\r\n <div\r\n class=\"d-flex justify-content-between mb-3 align-items-center position-relative\"\r\n >\r\n <div class=\"col-4 global-search position-relative\">\r\n\r\n <span\r\n\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Search all columns and press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n\r\n />\r\n <span\r\n *ngIf=\"tableSearch\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon position-absolute end-0 top-50 translate-middle-y me-2 cursor-pointer\"\r\n (click)=\"onSearchReset()\"\r\n title=\"Clear search\"\r\n ></span>\r\n\r\n </div>\r\n\r\n <!-- Date Picker Buttons -->\r\n <!-- Date Picker Section - Improved Version -->\r\n<div class=\"position-relative d-flex justify-content-center align-items-center ms-2 date-range-container\">\r\n\r\n <!-- Hidden Date Picker Input -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n bsDaterangepicker\r\n #picker=\"bsDaterangepicker\"\r\n [(ngModel)]=\"bsRangeValue\"\r\n [bsConfig]=\"bsConfig\"\r\n (bsValueChange)=\"onRangeSelected($event, picker)\"\r\n style=\"opacity: 0; width: 0; height: 0; position: absolute;\"\r\n />\r\n\r\n <!-- Left Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer me-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('left')\"\r\n title=\"Previous Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-left\"></span>\r\n </span>\r\n\r\n <!-- Date Range Label -->\r\n <span\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n class=\"text-primary date-range-label cursor-pointer\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Click to open calendar\"\r\n >\r\n {{ bsRangeValue[0] | timezoneFormat:prefs:'date' }} - {{ bsRangeValue[1] | timezoneFormat:prefs:'date' }}\r\n </span>\r\n\r\n <!-- Right Arrow Button -->\r\n <span\r\n class=\"text-primary cursor-pointer ms-2 date-range-btn arrow-btn\"\r\n (click)=\"navigateDate('right')\"\r\n title=\"Next Date Range\"\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0\"\r\n >\r\n <span class=\"bi bi-chevron-right\"></span>\r\n </span>\r\n\r\n\r\n\r\n</div>\r\n\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n\r\n <!-- Pivot Mode Button -->\r\n <!-- <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 header-icon\"\r\n (click)=\"togglePivotMode()\"\r\n [class.active]=\"pivotMode\"\r\n title=\"Toggle Pivot Mode\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pivot.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n </a> -->\r\n\r\n <div class=\"action-buttons-row d-flex\">\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"togglePicker(picker)\"\r\n title=\"Select Date Range\"\r\n >\r\n <span class=\"bi bi-calendar3 text-primary\"></span>\r\n <span class=\"label-hidden text-white\">Calendar</span>\r\n </a>\r\n <button\r\n *ngIf=\"bsRangeValue && bsRangeValue.length > 0 && !isDefaultDateRange\"\r\n type=\"button\"\r\n class=\"button button-small btn btn-active-danger border border-danger me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n (click)=\"clearDateRange()\"\r\n title=\"Clear Date Range\"\r\n >\r\n <span class=\"bi bi-x-circle text-danger\"></span>\r\n <span class=\"label-hidden text-white\">Clear</span>\r\n </button>\r\n</div>\r\n<ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"action-buttons-row\"\r\n *ngIf=\"getButtonPermission(button) && (!button.condition || (button.condition === '!isSingleDay' && !isSingleDay) || (button.condition === 'isSingleDay' && isSingleDay))\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button\"\r\n [title]=\"button.name\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"button.iconPath\"\r\n class=\"svg-icon\"\r\n ></span>\r\n <span\r\n class=\"label-hidden\"\r\n >{{ button.name }}</span\r\n >\r\n </a>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Calendar Button -->\r\n\r\n\r\n<!-- Existing filter, settings, etc. -->\r\n <div\r\n *ngIf=\"!showFilterRow\"\r\n class=\"cursor-pointer position-relative action-buttons-row\"\r\n (click)=\"toggleOpenFilter()\"\r\n [class.active]=\"showFilters\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Filters</span>\r\n </a>\r\n <span\r\n *ngIf=\"activeFilteredColumns?.length\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #0022ff;\r\n background-color: rgb(0, 60, 255);\r\n position: absolute;\r\n right: 16px;\r\n top: 10px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer d-none\"\r\n (click)=\"toggleActions('advance-filter')\"\r\n [class.active]=\"activeTopButton === 'advance-filter'\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/zoom-charge.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"cursor-pointer action-buttons-row\"\r\n (click)=\"toggleActions('setting')\"\r\n [class.active]=\"\r\n activeTopButton === 'setting' ||\r\n activeTopButton === 'table-layout' ||\r\n activeTopButton === 'table-presets' ||\r\n activeTopButton === 'show-hide-columns'\r\n \"\r\n >\r\n <!-- <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"data-grid-svg-icon top-icon me-2\"\r\n ></span> -->\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n class=\"button button-small btn btn-active-primary border border-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/settings-2.svg'\"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span class=\"label-hidden text-white\">Setting</span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"activeTopButton === 'setting'\"\r\n class=\"actions-dropdown mt-1 actions-dropdown-setting\"\r\n style=\"position: absolute\"\r\n >\r\n <div class=\"dropdown-menu show shadow custom-menu\">\r\n <!-- Table Layout -->\r\n <a\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-layout')\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/table-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Layout</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n <!-- Table Presets -->\r\n <a\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/list-details.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Table Presets</span\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </a>\r\n\r\n <!-- Columns -->\r\n <a\r\n *ngIf=\"!showSideMenu\"\r\n (click)=\"\r\n $event.stopPropagation(); toggleActions('show-hide-columns')\r\n \"\r\n class=\"dropdown-item d-flex justify-content-between align-items-center cursor-pointer\"\r\n >\r\n <span\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Columns</span\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <span class=\"muted-text\">{{ columnsCount }}</span>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </a>\r\n\r\n <div class=\"dropdown-divider\"></div>\r\n\r\n <!-- Filter -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"toggleOpenFilter(); activeTopButton = ''\"\r\n *ngIf=\"!showFilterRow\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 mt-1 cursor-pointer\"\r\n ></span>\r\n Filter\r\n </a>\r\n\r\n <!-- Download -->\r\n <a\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('csv')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n CSV Export\r\n </a>\r\n <a\r\n *ngIf=\"enableExport\"\r\n class=\"dropdown-item cursor-pointer\"\r\n (click)=\"downloadCsv('xlsx')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/download.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span>\r\n Excel Export\r\n </a>\r\n <!-- Font Family & Font Size -->\r\n <div class=\"px-2 pb-2 pt-2\">\r\n <div class=\"d-flex gap-2\">\r\n <!-- Font Family -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"fontFaimly\"\r\n (change)=\"onFontChange()\"\r\n >\r\n <option *ngFor=\"let font of fontFamilies\" [value]=\"font\">\r\n {{ font }}\r\n </option>\r\n </select>\r\n\r\n <!-- Font Size -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n (change)=\"onFontChange()\"\r\n [(ngModel)]=\"bodyTextFontsSize\"\r\n >\r\n <option *ngFor=\"let size of fontSizes\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Layout -->\r\n\r\n <ng-container *ngIf=\"activeTopButton === 'table-layout'\">\r\n <div\r\n *ngTemplateOutlet=\"tableLayout\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'table-presets'\">\r\n <div\r\n *ngTemplateOutlet=\"tablePreset\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n\r\n <!-- Table Presets -->\r\n <ng-container *ngIf=\"activeTopButton === 'show-hide-columns'\">\r\n <div\r\n *ngTemplateOutlet=\"showHideColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n style=\"position: absolute\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n <div>\r\n <!-- Example single danger button -->\r\n\r\n <!-- <button\r\n type=\"button\"\r\n class=\"btn btn-primary btn-sm d-flex gap-2 action-button\"\r\n (click)=\"toggleActions('actions')\"\r\n >\r\n Action\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/Vector.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <div\r\n *ngIf=\"activeTopButton === 'actions'\"\r\n class=\"actions-dropdown mt-1\"\r\n >\r\n <div class=\"dropdown-menu show\">\r\n <a class=\"dropdown-item\" href=\"#\">Action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Another action</a>\r\n <a class=\"dropdown-item\" href=\"#\">Something else here</a>\r\n <div class=\"dropdown-divider\"></div>\r\n <a class=\"dropdown-item\" href=\"#\">Separated link</a>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"showFilters && !showFilterRow\"\r\n class=\"top-filter-row border-top py-2 d-flex justify-content-between align-items-center\"\r\n [style.height.px]=\"topFilterRowHeight\"\r\n >\r\n <!-- LEFT SIDE (Filter tags + Filter button) -->\r\n <div class=\"d-flex gap-2 align-items-center\">\r\n <ng-container *ngIf=\"activeFilteredColumns?.length\">\r\n <div\r\n *ngFor=\"let col of activeFilteredColumns; trackBy: trackByField\"\r\n class=\"filter-tags\"\r\n >\r\n <div\r\n (click)=\"\r\n isActiveFilterOpen = true;\r\n activeTopButton = 'filter-columns';\r\n openFilter(col)\r\n \"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button active-filters\"\r\n style=\"white-space: nowrap\"\r\n [class.active]=\"\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen &&\r\n activeTopButton == 'filter-columns'\r\n \"\r\n >\r\n <span class=\"header-tag mt-0 d-flex align-items-center\">\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n {{ col.header }}\r\n <span\r\n (click)=\"\r\n $event.stopPropagation(); removeColumnFilterFromColumn(col)\r\n \"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"data-grid-svg-icon cross-secondary ms-2 mb-1\"\r\n ></span>\r\n </span>\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"\r\n activeTopButton === 'filter-columns' &&\r\n col?.field == selectedColumnForFilter?.field &&\r\n isActiveFilterOpen\r\n \"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns; context: { column: col }\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Filter Button -->\r\n <div class=\"add-filter-button-menu\">\r\n <div\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"d-flex justify-content-center align-items-center muted-text add-filter-button button-filter\"\r\n style=\"width: 70px\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/plus.svg'\"\r\n class=\"me-2 data-grid-svg-icon\"\r\n ></span>\r\n Filter\r\n </div>\r\n\r\n <ng-container\r\n *ngIf=\"activeTopButton === 'filter-columns' && !isActiveFilterOpen\"\r\n >\r\n <div\r\n *ngTemplateOutlet=\"filterColumns\"\r\n class=\"actions-dropdown mt-1\"\r\n ></div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT SIDE (Update + Reset) -->\r\n <div class=\"d-flex gap-3 align-items-center\">\r\n <div\r\n (click)=\"savePreset()\"\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!checkFilterChangesEffect()\"\r\n >\r\n Update View\r\n </div>\r\n\r\n <div\r\n class=\"text-primary cursor-pointer all-filters-reset-button\"\r\n *ngIf=\"!tableFilterViewId && activeFilteredColumns?.length\"\r\n (click)=\"clearAllFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height]=\"\r\n showFilters ? 'calc(100% - ' + topFilterRowHeight + 'px)' : '100%'\r\n \"\r\n cdkDropListGroup\r\n class=\"data-grid-table-wrapper overflow-hidden\"\r\n #dataGridContainer\r\n [style.fontFamily]=\"fontFaimly\"\r\n >\r\n <div\r\n *ngIf=\"showRowsGrouping\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [cdkDropListData]=\"columns\"\r\n [style.backgroundColor]=\"\r\n topGroupedBadgesBackgroundColor || headerBackgroundColor\r\n \"\r\n cdkDropList\r\n (cdkDropListEntered)=\"enterToTopRowGrouping($event)\"\r\n (cdkDropListExited)=\"exitedFromTheTopRow($event)\"\r\n (cdkDropListDropped)=\"onDropTopGroup($event)\"\r\n [cdkDropListEnterPredicate]=\"canEnterToRowsGrouping\"\r\n id=\"rows-grouping-top-container\"\r\n class=\"border-below d-flex px-4 align-items-center\"\r\n >\r\n <div class=\"d-flex gap-2 align-items-center me-5\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <div *ngIf=\"!draggingInGroupArea && !groupedColumns?.length\">\r\n Drag here to set row groups\r\n </div>\r\n <ng-container\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n groupedColumns.length > 1 && i != groupedColumns.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n\r\n\r\n\r\n</div>\r\n<div\r\n class=\"d-flex overflow-hidden\"\r\n [style.height]=\"\r\n 'calc(100% - ' +\r\n (showRowsGrouping\r\n ? headerRowHeight + footerRowHeight\r\n : footerRowHeight) +\r\n 'px)'\r\n \"\r\n>\r\n <div\r\n class=\"h-100\"\r\n [style.width]=\"\r\n !showSideMenu\r\n ? '100%'\r\n : sideMenuVisible\r\n ? 'calc(100% - 280px)'\r\n : 'calc(100% - 30px)'\r\n \"\r\n >\r\n <div class=\"h-100 transition position-relative w-100\">\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- Data Grid Header starts here -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n <!-- ##################################################################################################################################################################################### -->\r\n\r\n <div\r\n class=\"data-grid-header-wrapper w-100\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [class.border-below]=\"!hasAnyVisibleColumn\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Left Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div class=\"data-grid-header left-pinned\" #leftPinnedHeader>\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.width.px]=\"65\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n S.No</div>\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell border-below\"\r\n [style.height.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [indeterminate]=\"isIndeterminateState(dataSet)\"\r\n [checked]=\"isAllSelected(dataSet)\"\r\n (change)=\"toggleSelectAll(dataSet)\"\r\n />\r\n </div>\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n id=\"left-pinned-header\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"leftPinnedColumns\"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'left')\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewLeftPinnedColumns')\r\n \"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n style=\"min-width: 0.2px\"\r\n [style.background-color]=\"headerBackgroundColor\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of leftPinnedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewLeftPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: ''\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngIf=\"col?.children?.length; else singleCol\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Center Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n class=\"data-grid-header center-scrollable\"\r\n #centerPinnedHeader\r\n (scroll)=\"onCenterHeaderScroll($event)\"\r\n id=\"center-pinned-header\"\r\n cdkDropList\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n [cdkDropListData]=\"centerColumns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListSortingDisabled]=\"\r\n isDisableColumnGrouping && draggingInGroupArea\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'center')\"\r\n (cdkDropListSorted)=\"onSortGroup($event, 'previewCenterColumns')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n [style.maxWidth]=\"\r\n 'calc(100% - ' +\r\n (rightPinnedHeader.offsetWidth + leftPinnedHeader.offsetWidth) +\r\n 'px)'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"groupedColumns?.length\"\r\n style=\"min-width: 200px\"\r\n class=\"h-100 align-items-center\"\r\n #columnsGroupedBox\r\n id=\"groupBoxHeaderDiv\"\r\n >\r\n <div\r\n class=\"d-flex w-100 justify-content-between align-items-center border-below\"\r\n [style.height.px]=\"\r\n showFilterRow ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n >\r\n <div class=\"ps-3\">Group</div>\r\n <div class=\"d-flex\">\r\n <div\r\n class=\"three-dots cursor-pointer\"\r\n (click)=\"openThreeDotsMenu($event, 'group')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n (mousedown)=\"onResizeGroupBox($event)\"\r\n class=\"resize-handle\"\r\n style=\"margin-right: -2px\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [style.height.px]=\"headerRowHeight\"\r\n class=\"border-below\"\r\n ></div>\r\n </div>\r\n <!-- <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"gridType === 'TimeSheet' && !areDatesSelectedAndEqual\"\r\n >\r\n </span> -->\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col); dragStartOnGroup(col)\r\n \"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of centerColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'previewCenterColumns'\r\n }\r\n \"\r\n >\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container *ngIf=\"col?.is_groupable\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"!areDatesSelectedAndEqual\" class=\"header-cell border-below\" [style.width.px]=\"30\" [style.height.px]=\"headerRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\"></div>\r\n </div>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n cdkDropList\r\n id=\"right-pinned-header\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n cdkDropListOrientation=\"horizontal\"\r\n class=\"data-grid-header right-pinned\"\r\n (cdkDropListSorted)=\"\r\n onSortGroup($event, 'previewRightPinnedColumns')\r\n \"\r\n (cdkDropListEntered)=\"onDropListEnter($event, 'right')\"\r\n (cdkDropListDropped)=\"onDropGroup()\"\r\n #rightPinnedHeader\r\n class=\"right-pinned-header d-flex\"\r\n style=\"min-width: 0.2px\"\r\n >\r\n <div\r\n class=\"dragable-header\"\r\n cdkDrag\r\n [cdkDragData]=\"col\"\r\n *ngFor=\"\r\n let col of rightPinnedColumns;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n pinnedRight: true,\r\n index: i,\r\n section: 'previewRightPinnedColumns'\r\n }\r\n \"\r\n ></ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: {\r\n $implicit: col,\r\n index: i,\r\n section: 'centerColumns'\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container *ngIf=\"col?.children?.length; else singleCol\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron:\r\n col.children.length > 1 &&\r\n i != col.children.length - 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #singleCol>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: col,\r\n showChevron: col?.children?.length > 1\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!-- Data Grid Body starts here -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <!--########################################################################################################################################################################################################################### -->\r\n <div\r\n class=\"h-100 d-flex justify-content-center align-items-center\"\r\n *ngIf=\"!dataSet.length && !loading\"\r\n >\r\n No Record Found\r\n </div>\r\n\r\n <div\r\n class=\"position-absolute w-100 h-100 d-flex justify-content-center align-items-center loading-overlay\"\r\n *ngIf=\"loading\"\r\n style=\"\r\n z-index: 999;\r\n background: rgba(255, 255, 255, 0.8);\r\n backdrop-filter: blur(1px);\r\n \"\r\n >\r\n <div class=\"text-center p-2\">\r\n <div class=\"spinner-border text-primary\" role=\"status\"></div> Loading...\r\n</div>\r\n </div>\r\n\r\n <!-- Card View -->\r\n \r\n\r\n <!-- Table View -->\r\n <div\r\n class=\"data-grid-body-wrapper position-relative d-flex\"\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"overflow-y: auto; overflow-x: hidden\"\r\n #mainScroll\r\n (scroll)=\"onMainScroll($event)\"\r\n *ngIf=\"dataSet.length\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div [style.height.px]=\"!groupedColumns.length ? originalDataSet.length * rowHeight: 0\"></div>\r\n <div [class.h-100]=\"originalDataSet.length <= 10\">\r\n <div\r\n class=\"data-grid-body left-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n [class.transparent-border-right]=\"!hasLeftPinnedColumns\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewLeftPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n isLeft: true,\r\n section: 'left'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- CENTER -->\r\n <div\r\n class=\"\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewCenterColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'center'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT PINNED -->\r\n <div\r\n class=\"right-pinned-body-wrapper\"\r\n *ngIf=\"hasRightPinnedColumns\"\r\n [class.h-100]=\"originalDataSet.length <= 10\"\r\n [style.max-width.px]=\"isScrollbarVisible ? rightPinnedHeader.offsetWidth - 15: rightPinnedHeader.offsetWidth\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"\r\n 'translateY(' + startIndex * rowHeight + 'px)'\r\n \"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right'\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Vertical Fake scroll Bar -->\r\n <div\r\n (scroll)=\"onMainFakeScroll($event)\"\r\n class=\"fake-scrollbar fake-scrollbar-vertical d-none\"\r\n [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n [style.top.px]=\"\r\n showColumnsGrouping && showFilterRow\r\n ? headerRowHeight * 3\r\n : showColumnsGrouping || showFilterRow\r\n ? headerRowHeight * 2\r\n : headerRowHeight\r\n \"\r\n #fakeScroll\r\n [style.height]=\"bodyWrapperHeight\"\r\n style=\"\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n width: 17px;\r\n position: absolute;\r\n right: 0;\r\n background-color: f1f2f3;\r\n z-index: 10;\r\n \"\r\n >\r\n <div [style.height.px]=\"rowHeight * (paginationConfig.totalResults || flattenedData.length)\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"dataSet.length\">\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n (scroll)=\"onHorizintalFakeScroll($event)\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #horizintalFakeScroll\r\n [style.width.px]=\"centerPinnedHeader.offsetWidth\"\r\n >\r\n <div [style.width.px]=\"centerPinnedHeader.scrollWidth\"></div>\r\n </div>\r\n <div\r\n [style.scrollbarWidth]=\"horizintalScrollbarWidth\"\r\n class=\"fake-horizintal-scrollbar\"\r\n #fakeScroll\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n style=\"overflow-x: scroll\"\r\n ></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Side Menu Implemented Here -->\r\n <div\r\n *ngIf=\"showSideMenu && !hasOpenAccordion\"\r\n [style.width.px]=\"sideMenuVisible ? 280 : 30\"\r\n class=\"right-menu h-100\"\r\n [style.backgroundColor]=\"sidemenuBackgroundColor\"\r\n >\r\n <div class=\"h-100 d-flex flex-row-reverse\">\r\n <div\r\n style=\"width: 30px\"\r\n class=\"d-flex flex-column align-items-center cursor-pointer\"\r\n [class.border-start]=\"sideMenuVisible\"\r\n >\r\n <div\r\n (click)=\"toggleSideMenu('cols')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'cols' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"sideMenuVisible\"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n\r\n <div\r\n (click)=\"toggleSideMenu('filtrs')\"\r\n [class.bg-white]=\"\r\n currentOpenedSideMenue == 'filtrs' && sideMenuVisible\r\n \"\r\n [class.border-below]=\"\r\n sideMenuVisible && currentOpenedSideMenue == 'filtrs'\r\n \"\r\n class=\"columns-button d-flex flex-column align-items-center\"\r\n >\r\n <div>\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div>\r\n </div>\r\n <div\r\n class=\"h-100\"\r\n *ngIf=\"sideMenuVisible\"\r\n [ngStyle]=\"{ width: sideMenuVisible ? '250px' : '' }\"\r\n >\r\n <div class=\"h-100\">\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'cols' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"columnPannel\"></ng-container>\r\n <!-- Column Items -->\r\n <div class=\"column-panel-body px-3\">\r\n <ng-container\r\n *ngFor=\"let col of columns; trackBy: trackByField\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <hr />\r\n\r\n <div class=\"side-menu-row-groups\" style=\"height: 30%\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideMenuRowGroups\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container\r\n *ngIf=\"currentOpenedSideMenue == 'filtrs' && sideMenuVisible\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sideFilters\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div [style.height.px]=\"footerRowHeight\" class=\"border-top\">\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.selectedPageSize\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results: {{ paginationConfig.page }}-{{\r\n paginationConfig.page * paginationConfig.limit\r\n }}\r\n of\r\n {{ paginationConfig.totalResults }}\r\n </div>\r\n\r\n <div class=\"page-buttons\">\r\n <button\r\n (click)=\"goToPage(paginationConfig.page - 1)\"\r\n [disabled]=\"paginationConfig.page === 1\"\r\n >\r\n \u2039\r\n </button>\r\n\r\n <ng-container *ngFor=\"let page of visiblePages\">\r\n <button\r\n *ngIf=\"page !== '...'\"\r\n (click)=\"goToPage(page)\"\r\n [class.active]=\"page === paginationConfig.page\"\r\n >\r\n {{ page }}\r\n </button>\r\n <span *ngIf=\"page === '...'\">...</span>\r\n </ng-container>\r\n\r\n <button\r\n (click)=\"goToPage(paginationConfig.page + 1)\"\r\n [disabled]=\"paginationConfig.page === paginationConfig.totalResults\"\r\n >\r\n \u203A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- Header Cell Template -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n<!-- ------------------------------------------------------------------------------------------------------------------------ -->\r\n\r\n<ng-template\r\n #headerCell\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"section\"\r\n let-calledFromNestedPlaceholder=\"calledFromNestedPlaceholder\"\r\n>\r\n <div>\r\n <!-- Group Header -->\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatHeader\">\r\n <div cdkDroplistGroup class=\"group-column-wrapper\">\r\n <!-- Parent Header -->\r\n <div\r\n *ngIf=\"shouldTheGroupHeaderShow(col)\"\r\n class=\"header-cell group-header\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.gridColumn]=\"'span ' + col.children.length\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n [class.justify-content-end]=\"pinnedRight\"\r\n style=\"grid-row: 1\"\r\n >\r\n <div\r\n class=\"group-header-content\"\r\n [title]=\"col.header\"\r\n [class.ms-2]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(col.children)\"\r\n (mousedown)=\"onResizeGroup($event, col, pinnedRight)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Child Headers and Filters -->\r\n\r\n <div\r\n class=\"d-flex\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"col.children\"\r\n (cdkDropListSorted)=\"onChildDroplistSorted($event, sections)\"\r\n (cdkDropListDropped)=\"onChildDroplistDroped($event)\"\r\n [cdkDropListSortingDisabled]=\"false\"\r\n [cdkDropListConnectedTo]=\"\r\n showRowsGrouping ? ['rows-grouping-top-container'] : []\r\n \"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"child\"\r\n *ngFor=\"let child of col.children; let i = index\"\r\n >\r\n <!-- Child Header -->\r\n <ng-container *ngIf=\"child.is_visible && !child['isRowGrouped']\">\r\n <div\r\n cdkDragHandle\r\n class=\"header-cell one-row-header-cells cursor-pointer\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 2\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(child)\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100\"\r\n [class.editable-header]=\"child?.is_editable\"\r\n (click)=\"openThreeDotsMenu($event, child); openFilteronThreeDotsClick(child)\"\r\n >\r\n {{ child.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"child.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, child)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === child\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!child?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: { col: child }\r\n \"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n (dblclick)=\"autosizeColumn(child)\"\r\n (mousedown)=\"onResizeColumn($event, child)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"child.field\"\r\n [style.width.px]=\"child.width\"\r\n [style.min-width.px]=\"child.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(child)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(child)\"\r\n ><span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(child)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell?.field == child?.field\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"\r\n child?.pinned ? 0 : -centerPinnedHeader.scrollLeft\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: child }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div\r\n *ngIf=\"\r\n !draggingInGroupArea ||\r\n (child.is_groupable && draggingInGroupArea)\r\n \"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea && !child.is_groupable\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/ban.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template cdkDragPlaceholder>\r\n <div *ngIf=\"!draggingInGroupArea\" class=\"position-relative\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n childHeaderPlaceholder;\r\n context: {\r\n $implicit: child,\r\n index: i,\r\n sections: sections,\r\n calledFromNestedPlaceholder: true,\r\n }\r\n \"\r\n ></div>\r\n </div>\r\n <div\r\n *ngIf=\"draggingInGroupArea && child?.is_groupable\"\r\n class=\"d-flex gap-2 ms-2\"\r\n style=\"opacity: 0.6\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n topGroupingRowPlaceholder;\r\n context: {\r\n $implicit: child,\r\n showChevron: false,\r\n pinnedRight: pinnedRight,\r\n sections: sections,\r\n index: i\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Flat Header || Single Header Cell-->\r\n <ng-template #flatHeader>\r\n <div class=\"group-column-wrapper\">\r\n <!-- Full-height Header Cell (spans 2 rows visually) -->\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.min-height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.height.px]=\"\r\n showColumnsGrouping ? headerRowHeight * 2 : headerRowHeight\r\n \"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"grid-row: 1 / span 2\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between h-100 align-items-center w-100\"\r\n >\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center w-100\"\r\n [title]=\"col.header\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 cursor-pointer\"\r\n [class.editable-header]=\"col?.is_editable\"\r\n [class.filter-applied-on-text]=\"isFilterAppliedOnColumn(col)\"\r\n (click)=\"openThreeDotsMenu($event, col); openFilteronThreeDotsClick(col)\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n [class.me-2]=\"pinnedRight\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"col?.pinned\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div\r\n [class.me-2]=\"col.order_by\"\r\n class=\"d-flex align-items-center\"\r\n *ngIf=\"sortingConfig?.field == col.field\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (sortingConfig?.order_by == 'desc'\r\n ? 'data-grid/icons/sort-desc.svg'\r\n : 'data-grid/icons/sort-asc.svg')\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"openThreeDotsMenu($event, col)\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <!-- Only show menu if this column is active -->\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeCol === col\"\r\n style=\"top: -50%; z-index: 21\"\r\n [style.left.px]=\"\r\n -(!col?.pinned ? centerPinnedHeader.scrollLeft : 0)\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n\r\n <div\r\n class=\"resize-handle\"\r\n [class.w-100]=\"col.pinned == 'right'\"\r\n (dblclick)=\"autosizeColumn(col)\"\r\n (mousedown)=\"onResizeColumn($event, col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Filter Cell -->\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n (ngModelChange)=\"onFilterChange(col)\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"$event.stopPropagation(); openFilter(col)\"\r\n [class.filter-applied]=\"isFilterAppliedOnColumn(col)\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span\r\n *ngIf=\"isFilterAppliedOnColumn(col)\"\r\n style=\"\r\n width: 7px;\r\n height: 7px;\r\n box-shadow: 0px 0px 3px #7486ff;\r\n background-color: rgb(0 163 233);\r\n position: absolute;\r\n right: 4px;\r\n top: 12px;\r\n \"\r\n class=\"rounded-circle d-block\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute filter-row-filter-wrapper\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 99\"\r\n [style.left.px]=\"col?.pinned ? 0 : -centerPinnedHeader.scrollLeft\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- Body Cell Template -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n<!-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -->\r\n\r\n<ng-template\r\n #rowCell\r\n let-row\r\n let-columns=\"columns\"\r\n let-isEven=\"isEven\"\r\n let-isOdd=\"isOdd\"\r\n let-isLeftSection=\"isLeft\"\r\n let-section=\"section\"\r\n let-rowIndex=\"rowIndex\"\r\n>\r\n <!-- Check if row is a group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"groupRowTemplate; context: { $implicit: row, depth: 0 }\"\r\n ></ng-container>\r\n <ng-template #groupRowTemplate let-row let-depth=\"depth\">\r\n <ng-container *ngIf=\"row.isGroup; else regularRow\">\r\n <!-- Group Header -->\r\n <div\r\n class=\"group-header-row border-below d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.width]=\"\r\n section == 'center'\r\n ? centerScrollableBody!.nativeElement?.scrollWidth + 'px'\r\n : '100%'\r\n \"\r\n >\r\n <div\r\n *ngIf=\"section == 'left'\"\r\n class=\"h-100 d-flex\"\r\n [style.width.px]=\"leftPinnedHeader.offsetWidth - 1\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n >\r\n <div\r\n *ngIf=\"showSerialNumber\"\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center h-100 border-right justify-content-end pe-2 s-no\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [style.width.px]=\"65\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n style=\"width: 50px\"\r\n class=\"d-flex align-items-center justify-content-center h-100 border-right\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input style=\"width: 16px; height: 16px\" type=\"checkbox\" />\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'center'\"\r\n [style.width.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <div\r\n class=\"d-flex align-items-center justify-content-between\"\r\n [style.paddingLeft.px]=\"depth > 0 ? depth * 16 : 0\"\r\n >\r\n <span class=\"me-2 filter-icon-wrapper\" (click)=\"toggleExpand(row)\">\r\n <span\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <strong (click)=\"toggleExpand(row)\" class=\"cursor-pointer\">\r\n {{ row.groupValue }} ({{ countLeafRows(row) }})\r\n </strong>\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"section == 'right'\"\r\n [style.width.px]=\"rightPinnedHeader.offsetWidth\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n ></div>\r\n </div>\r\n\r\n <!-- Recursive Children -->\r\n <div class=\"group-children\" *ngIf=\"row.isExpand\">\r\n <ng-container\r\n *ngFor=\"let child of row.children; let i = index; trackBy: trackById\"\r\n >\r\n <ng-container *ngIf=\"child.isGroup; else dataRow\">\r\n <!-- Recursive call for nested group -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n groupRowTemplate;\r\n context: { $implicit: child, depth: depth + 1 }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #dataRow>\r\n <!-- Regular data row -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: child,\r\n columns: columns,\r\n isEven: i % 2 === 0,\r\n isOdd: i % 2 !== 0,\r\n isLeft: isLeftSection,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Regular row (not a group) -->\r\n <ng-template #regularRow>\r\n <div class=\"d-flex\" [style.height.px]=\"rowHeight\">\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'start' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n <div\r\n [style.min-width.px]=\"\r\n section == 'center' && groupedColumns!.length ? groupBoxPadding : 0\r\n \"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row h-100\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row, row?.details?.data?.length ? 'accordion-parent' : 'main')\"\r\n [style.height.px]=\"rowHeight\"\r\n class=\"data-grid-row\"\r\n [class.even-row]=\"isEven\"\r\n [class.odd-row]=\"isOdd\"\r\n [class.hovered-row]=\"hoveredRowId === (row._id || row.id)\"\r\n (mouseenter)=\"onRowHover(row)\"\r\n (mouseleave)=\"onRowLeave()\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <div\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n class=\"select-all-checkbox-cell justify-content-end pe-2 s-no\"\r\n [style.width.px]=\"65\"\r\n *ngIf=\"isLeftSection && showSerialNumber\"\r\n [style.cursor]=\"\r\n 'url(' +\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/arrow-right.svg), auto'\r\n \"\r\n (mousedown)=\"onRowMouseDown(row.__virtualIndex, $event)\"\r\n (mouseover)=\"onRowMouseOver(row.__virtualIndex, $event)\"\r\n >\r\n {{ row.__virtualIndex }}\r\n </div>\r\n <div\r\n [style.backgroundColor]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n ? selectedRowsBackgroundColor\r\n : checkboxesBackgroundColor\r\n \"\r\n class=\"select-all-checkbox-cell\"\r\n *ngIf=\"isLeftSection\"\r\n [class.left-selection-border]=\"\r\n rowSelectedIndexes.has(row.__virtualIndex)\r\n \"\r\n [class.first-row-selected]=\"firstSelectedRow == row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow == row.__virtualIndex\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row)\"\r\n (change)=\"toggleRowSelection(row)\"\r\n />\r\n </div>\r\n\r\n <!-- Render all columns -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns;\r\n trackBy: trackByField;\r\n let colIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.children?.length > 0; else flatColumn\">\r\n <ng-container\r\n *ngFor=\"\r\n let child of col.children;\r\n trackBy: trackByField;\r\n let subColIndex = index\r\n \"\r\n >\r\n <ng-container *ngIf=\"child?.is_visible && !child?.isRowGrouped\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: child,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: subColIndex,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-template #flatColumn>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n cellTemplate;\r\n context: {\r\n col: col,\r\n row: row,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n subColIndex: null,\r\n section: section\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <span\r\n class=\"d-flex align-items-center justify-content-center cursor-pointer border-below\"\r\n style=\"min-width: 30px; height: 100%;\"\r\n *ngIf=\"section == 'center' && gridType === 'TimeSheet' && detailsIconPosition === 'end' && !areDatesSelectedAndEqual\"\r\n [ngStyle]=\"{\r\n 'background-color':\r\n hoveredRowId === (row._id || row.id)\r\n ? rowHoverColor\r\n : isRowSelected(row)\r\n ? checkedRowBackgroundColor\r\n : isEven\r\n ? evenRowsBackgroundColor\r\n : oddRowsBackgroundColor\r\n }\"\r\n >\r\n <span\r\n (click)=\"row.isDetailsExpand = !row.isDetailsExpand\"\r\n *ngIf=\"row?.details?.data?.length\"\r\n class=\"data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n row.isDetailsExpand\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n ></span>\r\n </span>\r\n </div>\r\n <!-- LEFT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'left' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" [style.color]=\"headerTextColor\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n<!-- CENTER SECTION: Actual details table -->\r\n\r\n<div *ngIf=\"section === 'center' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details-wrapper data-grid-accordion\" [style.fontFamily]=\"fontFaimly\" [style.fontSize.px]=\"bodyTextFontsSize\" style=\"display: flex; width: 100%; max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <!-- LEFT SECTION OF ACCORDION -->\r\n <div #leftContainer class=\"accordion-left-section data-pin-body-wrapper data-grid-accordion-section\" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailLeftScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4 border-right\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'left'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'left')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'left')\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n (dblclick)=\"enableDetailEdits(row, d, col)\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <!-- Use the same rendering logic as center section -->\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default fallback -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- CENTER SECTION OF ACCORDION (WITH VIRTUAL SCROLL) -->\r\n\r\n<div class=\"accordion-center-section data-grid-accordion-section\" style=\"flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;\">\r\n <!-- Header Section -->\r\n <div class=\"header-container\" style=\"overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;\" #headerContainer (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <thead>\r\n <tr\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n cdkDropList\r\n [cdkDropListData]=\"row?.details.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let i = index\">\r\n <th\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n cdkDrag\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.color]=\"headerTextColor\"\r\n [style.fontSize.px]=\"headerTextFontsSize\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n style=\"cursor: move; position: relative;\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span *ngIf=\"col.pinned\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\" class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span\r\n class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n </div>\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\" [style.top.px]=\"nestedTableHeaderRowHeight\" [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <!-- Group Badges (if any) -->\r\n <div *ngIf=\"row.details?.groupedColumns?.length\" class=\"detail-group-badges\">\r\n <span *ngFor=\"let g of row.details.groupedColumns; trackBy: trackByField\" class=\"badge bg-light text-dark me-1\">\r\n {{ g.header }}\r\n <span class=\"ms-1 cursor-pointer\" (click)=\"ungroupDetailColumn(g, row)\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"></span>\r\n </span>\r\n </div>\r\n\r\n <!-- Data Table Section with Virtual Scroll -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"{{ nestedTablerowHeight }}\"\r\n minBufferPx=\"200\"\r\n maxBufferPx=\"400\"\r\n class=\"detail-virtual-scroll\"\r\n [attr.data-detail-row-id]=\"row._id || row.id\"\r\n style=\"flex: 1; overflow: auto;\"\r\n #dataContainer\r\n (scroll)=\"syncVerticalScroll($event)\"\r\n (scroll)=\"syncScroll($event)\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-borders]=\"showVerticalBorder\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: 100%;\">\r\n <tbody>\r\n <tr\r\n class=\"cursor-pointer data-grid-accordion-row\"\r\n *cdkVirtualFor=\"let d of row.details.data; trackBy: trackById; let j = index\"\r\n (contextmenu)=\"onRightClick($event, d, 'accordion-child')\"\r\n [style.height.px]=\"nestedTablerowHeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns; let k = index\">\r\n <td\r\n *ngIf=\"col.is_visible !== false && !col.pinned\"\r\n class=\"px-4\"\r\n (mousedown)=\"startDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, k, col.field, $event, 'center')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, k, col.field, 'center')\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\"\r\n style=\"cursor: pointer; position: relative; overflow: visible; cursor: cell; \">\r\n <div class=\"time-sheet-container\" style=\"overflow: visible; display: flex; gap: 4px; align-items: center; height: 100%; justify-content: center;\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.field === 'short_breaks'; else defaultDetailCell\">\r\n <ng-container *ngIf=\"col.field === 'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaks\">\r\n <span *ngFor=\"let breakItem of d[col.field]; let breakIndex = index\"\r\n class=\"circle-value badge-outline break-on text-center\"\r\n [ngClass]=\"(breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'paid' ? 'break-color-paid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'unpaid' ? 'break-color-unpaid' : (breakItem.break_type?.data_value_name?.toLowerCase() || breakItem.breakType?.toLowerCase()) === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showBreakTooltip($event, breakItem)\"\r\n (mouseleave)=\"hideBreakTooltip()\">\r\n {{ breakItem.break_duration }}m\r\n</span>\r\n </ng-container>\r\n <ng-template #noBreaks>\r\n <div\r\n \r\n >\r\n -\r\n</div>\r\n</ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"col.field === 'short_breaks' && !isDetailEditing(row, d, col)\">\r\n <div *ngIf=\"d[col.field]?.duration; else noShortBreak\"\r\n class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n</ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <input #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" [attr.data-edit-key]=\"row._id + '-' + j + '-' + col.field\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto; position: absolute; top: 0; left: 0; z-index: 10;\" />\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #defaultDetailCell>\r\n <span class=\"d-flex align-items-center h-100\">\r\n <ng-container *ngIf=\"!isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- \u2705 SHORT LEAVE: Progress bar in detail rows -->\r\n <div *ngSwitchCase=\"'short_leave'\" class=\"position-relative\" style=\"min-width: 100px; width: 150px;\">\r\n <ng-container *ngIf=\"d.short_leave && d.short_leave.length > 0; else noShortLeaveDetail\">\r\n <div\r\n class=\"w-100 d-flex main-progress-bar\"\r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, d)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\"\r\n >\r\n <span\r\n class=\"d-block\"\r\n [style.min-width.%]=\"d.short_leave[0].short_leave_time_percentage\"\r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"\r\n ></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">{{ d.short_leave[0].short_leave_time_percentage }}%</span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveDetail>\r\n <div >-</div>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Status -->\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Existing cases -->\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"popover__wrapper\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n <div *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\" class=\"data-grid-svg-icon text-primary\" style=\"cursor: pointer; font-size: 16px;\" (mouseenter)=\"showManualLogsTooltip($event, row, d)\" (mouseleave)=\"hideManualLogsTooltip()\"></span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\" class=\"data-grid-svg-icon text-muted\" style=\"font-size: 16px; cursor: not-allowed;\"></span>\r\n </ng-template>\r\n </div>\r\n\r\n <!-- Default fallback -->\r\n <span *ngSwitchDefault>\r\n {{\r\n col.type === 'date'\r\n ? (getNestedValue(d, col.field) ? (getNestedValue(d, col.field) | timezoneFormat:prefs:'date') : '-')\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(d, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-')\r\n }}\r\n </span>\r\n</ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isDetailEditing(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <input *ngSwitchCase=\"'string'\" #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'number'\" #detailInput type=\"number\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'date'\" #detailInput type=\"date\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'time'\" #detailInput type=\"time\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n <input *ngSwitchCase=\"'currency'\" #detailInput type=\"number\" step=\"0.01\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm text-end\" style=\"width: 100%; height: auto;\" />\r\n <select *ngSwitchCase=\"'dropdown'\" #detailInput [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\">\r\n <option *ngFor=\"let option of col.column_dropdown_value\" [ngValue]=\"option?.value || option\">\r\n {{ option?.label || option?.name || option }}\r\n </option>\r\n </select>\r\n <input *ngSwitchDefault #detailInput type=\"text\" [ngModel]=\"getNestedValue(d, col.field)\" (blur)=\"disableDetailEdits(row, d, col)\" (keydown.enter)=\"disableDetailEdits(row, d, col)\" (keydown.escape)=\"disableDetailEdits(row, d, col)\" class=\"form-control form-control-sm\" style=\"width: 100%; height: auto;\" />\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </ng-template>\r\n </div>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </cdk-virtual-scroll-viewport>\r\n</div>\r\n\r\n <!-- RIGHT SECTION OF ACCORDION -->\r\n <div #rightContainer class=\"accordion-right-section data-pin-body-wrapper \" [attr.data-detail-row-id]=\"row._id || row.id\" (scroll)=\"onDetailRightScroll($event, row)\" style=\"flex-shrink: 0; overflow-y: auto; overflow-x: hidden;\">\r\n <table class=\"nested-table table-sm mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\" style=\"table-layout: fixed; width: auto;\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\" [style.color]=\"headerTextColor\" [style.fontSize.px]=\"headerTextFontsSize\" [style.fontWeight]=\"headerFontWeight\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; trackBy: trackByField\">\r\n <th *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [style.width.px]=\"col.width || 150\"\r\n [style.min-width.px]=\"col.width || 150\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\">\r\n <div class=\"d-flex justify-content-between align-items-center\" style=\"width: 100%;\">\r\n <span class=\"d-flex align-items-center gap-1\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"></span>\r\n {{ col.header }}\r\n </span>\r\n <span class=\"three-dots p-1\"\r\n (click)=\"openDetailThreeDotsMenus($event, col, row); activeDetailCol = col; activeDetailRow = row\"\r\n style=\"cursor: pointer;\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\" class=\"data-grid-svg-icon\"></span>\r\n </span>\r\n</div>\r\n\r\n <div class=\"resize-handles\" (mousedown)=\"onResizeDetailColumn($event, row, col)\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\" class=\"data-grid-svg-icon text-primary\"></span>\r\n </div>\r\n <ng-container *ngIf=\"activeDetailCol?.field == col.field && activeDetailRow === row\">\r\n <div class=\"position-absolute detail-column-menu-wrapper\"\r\n [style.top.px]=\"nestedTableHeaderRowHeight\"\r\n [style.left.px]=\"0\">\r\n <ng-container *ngTemplateOutlet=\"detailColumnMenu; context: { col: col, row: row }\"></ng-container>\r\n </div>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"rowHeight\" *ngFor=\"let d of row.details.data; let j = index; trackBy: trackById\">\r\n <ng-container *ngFor=\"let col of row.details.columns | pinnedColumns:'right'; let localK = index; trackBy: trackByField\">\r\n <td *ngIf=\"col.is_visible !== false\"\r\n class=\"px-4\"\r\n [attr.field]=\"col.field\"\r\n [attr.pinned]=\"col.pinned\"\r\n (mousedown)=\"startDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n (mouseenter)=\"extendDetailSelection(row, j, localK, col.field, $event, 'right')\"\r\n [class.selected-cell]=\"isDetailCellSelected(row, j, localK, col.field, 'right')\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell-detail]=\"isActiveDetailCell(row, d, col)\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n\r\n <ng-container *ngSwitchCase=\"'manually_logs'\" class=\"d-flex justify-content-start align-items-center pointer position-relative\">\r\n <ng-container *ngIf=\"d.manually_logs?.length > 0; else noManualLogsIcon\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon text-primary\"\r\n style=\"cursor: pointer; font-size: 16px;\"\r\n (mouseenter)=\"showManualLogsTooltip($event, row, d)\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n </span>\r\n </ng-container>\r\n <ng-template #noManualLogsIcon>\u2013</ng-template>\r\n</ng-container>\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.length; else noBreaksLeft\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(d[col.field])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onDetailBadgeOverflowCountClick(col, d)\">\r\n</app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksLeft>\r\n <div>\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <div *ngSwitchCase=\"'is_un_restricted'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" (mouseenter)=\"showRestrictionTooltip($event, row, d); preventRestrictionTooltipHide()\" (mouseleave)=\"hideRestrictionTooltip()\">\r\n <span class=\"\" [class.restriction-indicator]=\"row.attendance_log_detail?.length > 0\">\r\n {{ d.is_un_restricted ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"\" >\r\n {{ d.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"d[col.field]?.duration; else noShortBreakLeft\">\r\n <div class=\"circle-value\"\r\n [ngClass]=\"(d[col.field].type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (d[col.field].type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (d[col.field].type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\"\r\n (mouseenter)=\"showShortBreakTooltip($event, d[col.field], 'single_break'); preventCustomTooltipHide()\"\r\n (mouseleave)=\"hideShortBreakTooltip()\"\r\n (dblclick)=\"onShortBreakClick.emit(d)\">\r\n {{ d[col.field].duration }}m\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortBreakLeft>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n<ng-container *ngSwitchCase=\"'status'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noStatus\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noStatus>-</ng-template>\r\n</ng-container>\r\n\r\n<!-- Attendance Status -->\r\n<ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <ng-container *ngIf=\"getNestedValue(d, col.field); else noAttendanceStatus\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(d, col.field))\">\r\n {{ transformStatus(getNestedValue(d, col.field)) }}\r\n </span>\r\n </ng-container>\r\n <ng-template #noAttendanceStatus>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(d, col.field)?.value || getNestedValue(d, col.field)?.name || getNestedValue(d, col.field) || '-' }}\r\n </ng-container>\r\n</ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</tbody>\r\n </table>\r\n\r\n </div>\r\n\r\n <!-- DETAIL SIDE MENU (Sticky on right end) -->\r\n <div class=\"detail-side-menu-wrapper\" >\r\n <div style=\"width: 30px\" class=\"d-flex flex-column align-items-center \">\r\n <div (click)=\"toggleDetailSideMenu(row, 'cols')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'cols'\" class=\"columns-button d-flex flex-column align-items-center border-below\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Columns</div>\r\n </div>\r\n <!-- <div (click)=\"toggleDetailSideMenu(row, 'filtrs')\" [class.bg-white]=\"row.details.sideMenu?.currentTab === 'filtrs'\" class=\"columns-button d-flex flex-column align-items-center\">\r\n <span [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\" class=\"data-grid-svg-icon\"></span>\r\n <div class=\"side-menue-text\">Filter</div>\r\n </div> -->\r\n </div>\r\n\r\n <div *ngIf=\"row.details.sideMenu?.currentTab\" class=\"detail-side-menu-content\" [style.backgroundColor]=\"sidemenuBackgroundColor\" style=\"width: 250px; box-shadow: -2px 0 5px rgba(0,0,0,0.1);\">\r\n <!-- COLUMNS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'cols'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Columns</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"d-flex align-items-center mb-2\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\" [(ngModel)]=\"col.is_visible\" (change)=\"onDetailColumnVisibilityChange(row)\" />\r\n <span>{{ col.header }}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- FILTERS TAB -->\r\n <ng-container *ngIf=\"row.details.sideMenu.currentTab === 'filtrs'\">\r\n <div class=\"px-3 py-2 border-bottom d-flex align-items-center\">\r\n <strong class=\"me-auto\">Filters</strong>\r\n <input type=\"text\" class=\"form-control form-control-sm\" placeholder=\"Search...\" [(ngModel)]=\"row.details.sideMenu.columnSearch\" style=\"width: 120px; font-size: 12px;\" />\r\n </div>\r\n <div class=\"side-menu-scrollable\">\r\n <div *ngFor=\"let col of row.details.columns | filter: row.details.sideMenu.columnSearch:'header'; trackBy: trackByField\" class=\"mb-3\">\r\n <div class=\"d-flex justify-content-between align-items-center cursor-pointer\" (click)=\"col.expandedFilter = !col.expandedFilter\">\r\n <label class=\"mb-0 small\">{{ col.header }}</label>\r\n <span class=\"toggle-icon data-grid-svg-icon\" [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\" [class.rotate]=\"col.expandedFilter\"></span>\r\n </div>\r\n <div *ngIf=\"col.expandedFilter\" class=\"mt-2 filter-input-container ps-3 pe-3\">\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.length == col.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllDetailFilters(col, row, $event)\"\r\n id=\"detail_selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : col.searchValue : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n row.details.filters[col.field]?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onDetailOptionToggle(col, option, row)\"\r\n id=\"detail_option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'detail_option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].first_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field]?.first_value\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"and\"\r\n id=\"detail_and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"or\"\r\n id=\"detail_or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"detail_condition_{{ col.field }}\"\r\n [(ngModel)]=\"row.details.filters[col.field].condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n value=\"none\"\r\n id=\"detail_none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"detail_none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"row.details.filters[col.field].condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_condition\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n >\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"row.details.filters[col.field].second_value\"\r\n (ngModelChange)=\"applyDetailRowFilter(row)\"\r\n />\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Side Menu -->\r\n\r\n\r\n\r\n<!-- Popover for Restriction Logs (is_un_restricted) -->\r\n<div\r\n *ngIf=\"restrictionTooltipVisible\"\r\n class=\"popover__content m-l-10 popoverRestriction position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"restrictionTooltipPosition.x\"\r\n [style.top.px]=\"restrictionTooltipPosition.y\"\r\n (mouseenter)=\"preventRestrictionTooltipHide()\"\r\n (mouseleave)=\"hideRestrictionTooltip()\"\r\n style=\"z-index: 1000; min-width: 300px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\">Clock in</th>\r\n <th class=\"center\">Clock out</th>\r\n <th class=\"center\">Log Hr</th>\r\n <th class=\"center\">Log Min</th>\r\n <th class=\"center pe-2\">Status</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentRestrictionLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\"> {{ item?.clock_in_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.clock_out_time | date:'shortTime'}}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_hours }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ item?.logged_minutes }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ item?.status ? (item.status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Popover for Manual Logs -->\r\n<div\r\n *ngIf=\"manualLogsTooltipVisible\"\r\n class=\"popover__content position-absolute border rounded bg-white p-3\"\r\n [style.left.px]=\"manualLogsTooltipPosition.x\"\r\n [style.top.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\"\r\n style=\"z-index: 1000; min-width: 500px; font-size: 12px;\"\r\n>\r\n <div class=\"modal-area px-0 py-0\">\r\n <ng-container *ngIf=\"currentManualLogs.length > 0; else noManualLogs\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-row-primary-100 gs-0 gy-2 mb-0\">\r\n <thead>\r\n <tr class=\"fw-bolder text-muted bg-light\">\r\n <th class=\"center ps-2\" style=\"width: 18%;\">Name</th>\r\n <th class=\"center\">Date/Time</th>\r\n <th class=\"center\">Previous Time</th>\r\n <th class=\"center\">Updated Time</th>\r\n <th class=\"center\">Status</th>\r\n <th class=\"center pe-2\">Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let log of currentManualLogs\">\r\n <td class=\"center ps-2\">\r\n <span class=\"text-primary\">{{ log.name }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.date_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.previous_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"text-primary\">{{ log.updated_time }}</span>\r\n </td>\r\n <td class=\"center\">\r\n <span class=\"badge bg-light text-dark border\">\r\n {{ log.log_status ? (log.log_status | titlecase) : 'N/A' }}\r\n </span>\r\n </td>\r\n <td class=\"center pe-2\">\r\n <span class=\"text-primary\">{{ log.remarks }}</span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <ng-template #noManualLogs>\r\n <div class=\"text-center p-3\">\r\n <p class=\"text-muted mb-0\">No manual logs available for this record.</p>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Existing Custom Tooltip for Breaks -->\r\n\r\n\r\n\r\n\r\n\r\n <!-- RIGHT PINNED: Empty table to keep alignment -->\r\n <div *ngIf=\"section === 'right' && row.isDetailsExpand && !isSingleDay\" class=\"accordion-details data-grid-accordion-section\" style=\"max-height: 350px; min-height: 350px; overflow: hidden;\">\r\n <table class=\"nested-table table table-sm w-100 mb-0 data-grid-accordion-table\" [class.show-shadow]=\"rowShadingEnabled\">\r\n <thead>\r\n <tr [style.height.px]=\"nestedTableHeaderRowHeight\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <th *ngFor=\"let _ of [1, 2, 3, 4, 5]\">&nbsp;</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr [style.height.px]=\"nestedTablerowHeight\" *ngFor=\"let _ of row.details.data\" [style.backgroundColor]=\"headerBackgroundColor\">\r\n <td *ngFor=\"let __ of [1, 2, 3, 4, 5]\">&nbsp;</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n </ng-template>\r\n</ng-template>\r\n\r\n<!-- Actual Cell is Here -->\r\n<ng-template\r\n #cellTemplate\r\n let-col=\"col\"\r\n let-row=\"row\"\r\n let-section=\"section\"\r\n let-subColIndex=\"subColIndex\"\r\n let-rowIndex=\"rowIndex\"\r\n let-colIndex=\"colIndex\"\r\n>\r\n <div\r\n (click)=\"disableEdit(row, col); setActiveCell(row, col)\"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.fontSize.px]=\"bodyTextFontsSize\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n [class.row-selected]=\"rowSelectedIndexes.has(row.__virtualIndex)\"\r\n [class.first-row-selected]=\"firstSelectedRow === row.__virtualIndex\"\r\n [class.last-row-selected]=\"lastSelectedRow === row.__virtualIndex\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"$event.preventDefault(); enableEdit(row, col)\"\r\n (mousedown)=\"\r\n startSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseenter)=\"\r\n extendSelection(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n $event,\r\n section\r\n )\r\n \"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"\r\n isSelected(\r\n row.__virtualIndex,\r\n colIndex,\r\n subColIndex ?? 0,\r\n col.field,\r\n section\r\n )\r\n \"\r\n [class.top-border]=\"\r\n isTopBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-border]=\"\r\n isBottomBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.left-border]=\"\r\n isLeftBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.right-border]=\"\r\n isRightBorder(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-left-corner]=\"\r\n isTopLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.top-right-corner]=\"\r\n isTopRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-left-corner]=\"\r\n isBottomLeftCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n [class.bottom-right-corner]=\"\r\n isBottomRightCorner(row.__virtualIndex, colIndex, subColIndex, section)\r\n \"\r\n >\r\n <!-- (mousedown)=\"startSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseenter)=\"extendSelection(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field, $event)\"\r\n (mouseup)=\"endSelection()\"\r\n [class.selected-cell]=\"isSelected(row.__virtualIndex, colIndex, subColIndex ?? 0, col.field)\" -->\r\n <div class=\"table-cell\" [class.active-for-editing]=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50\">\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"isEditing(row, col) && getNestedValue(row, col.field)?.length <= 50; else viewMode\"\r\n >\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- Text Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 10\"\r\n *ngSwitchCase=\"'input'\"\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Number Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'number'\"\r\n #numberInput=\"ngModel\"\r\n #numberRef\r\n (keypress)=\"allowOnlyNumbers($event)\"\r\n type=\"number\"\r\n required\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n (keydown.enter)=\"numberRef.blur()\"\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': numberInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Date Input -->\r\n <input\r\n [style.height.px]=\"rowHeight - 8\"\r\n *ngSwitchCase=\"'date'\"\r\n type=\"date\"\r\n [(ngModel)]=\"row[col.field]\"\r\n (blur)=\"disableEdit(row, col)\"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n #dateInput=\"ngModel\"\r\n [ngClass]=\"{\r\n 'is-invalid': dateInput.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n\r\n <!-- Dropdown -->\r\n <!-- ng-select like dropdown -->\r\n <div\r\n *ngSwitchCase=\"'dropdown'\"\r\n class=\"dropdown w-100\"\r\n (blur)=\"disableEdit(row, col)\"\r\n >\r\n <!-- Trigger -->\r\n <button\r\n class=\"form-select form-select-sm text-start w-100 text-ellipsis\"\r\n type=\"button\"\r\n data-bs-toggle=\"dropdown\"\r\n aria-expanded=\"false\"\r\n [style.minHeight.px]=\"rowHeight - 10\"\r\n data-bs-display=\"static\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container>\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </ng-container>\r\n <ng-template #placeholder> Select options... </ng-template>\r\n </button>\r\n\r\n <!-- Menu -->\r\n <div\r\n class=\"dropdown-menu w-100 p-0 cell-editing-dropdown-menu rounded-3\"\r\n [class.show]=\"isEditing(row, col)\"\r\n >\r\n <!-- Search -->\r\n <div class=\"px-2 py-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"editinDropdownSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Options -->\r\n <div\r\n class=\"cell-editin-dropdown\"\r\n style=\"max-height: 200px; overflow: auto\"\r\n >\r\n <div\r\n (click)=\"\r\n setNestedValue(row, col, option, true);\r\n disableEdit(row, col)\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center item\"\r\n *ngFor=\"\r\n let option of col.column_dropdown_value\r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0\"\r\n [for]=\"col.field + '-' + option.value || option\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <input\r\n *ngSwitchCase=\"'email'\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #emailModel=\"ngModel\"\r\n #emailInput\r\n type=\"email\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n pattern=\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\"\r\n (blur)=\"disableEdit(row, col, emailModel)\"\r\n (keydown.enter)=\"\r\n emailModel.control.markAsTouched(); emailInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': emailModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n <!-- Default fallback -->\r\n <input\r\n *ngSwitchDefault\r\n [style.height.px]=\"rowHeight - 10\"\r\n [style.maxHeight.px]=\"rowHeight - 10\"\r\n #textModel=\"ngModel\"\r\n #textInput\r\n type=\"text\"\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"\r\n textModel.control.markAsTouched(); textInput.blur()\r\n \"\r\n autofocus\r\n class=\"form-control form-control-sm\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-between items-center w-100\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Text cell -->\r\n <div class=\"d-flex align-items-center w-100\">\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"\r\n col.type === 'date'\r\n ? (getNestedValue(row, col.field) | date : dateFormat)\r\n : getNestedValue(row, col.field)\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container [ngSwitch]=\"col.field\">\r\n <!-- Breaks -->\r\n <ng-container *ngSwitchCase=\"'breaks'\">\r\n <ng-container *ngIf=\"getNestedValue(row, 'breaks')?.length; else noBreaksMain\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, 'breaks'))\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-template #noBreaksMain>\r\n <div >\r\n -\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Breaks -->\r\n <ng-container *ngSwitchCase=\"'short_breaks'\">\r\n <ng-container *ngIf=\"row.short_breaks?.duration && row.short_breaks.duration > 0; else noShortBreak\">\r\n <span class=\"popover__wrapper d-flex justify-content-center align-items-center\" style=\"cursor: pointer;\" (dblclick)=\"onShortBreakClick.emit(row)\" (mouseenter)=\"showShortBreakTooltip($event, row.short_breaks)\" (mouseleave)=\"hideShortBreakTooltip()\">\r\n <span class=\"circle-value badge-outline text-center\" [ngClass]=\"(row.short_breaks.type || '').toLowerCase() === 'paid' ? 'break-color-paid' : (row.short_breaks.type || '').toLowerCase() === 'unpaid' ? 'break-color-unpaid' : (row.short_breaks.type || '').toLowerCase() === 'lunch' ? 'break-color-lunch' : 'break-color-default'\">\r\n {{ row.short_breaks.duration }}m\r\n </span>\r\n </span>\r\n </ng-container>\r\n <ng-template #noShortBreak>\r\n <div >-</div>\r\n </ng-template>\r\n </ng-container>\r\n\r\n <!-- Short Leave -->\r\n <!-- Short Leave -->\r\n<ng-container *ngSwitchCase=\"'short_leave'\">\r\n <ng-container *ngIf=\"row.short_leave && row.short_leave.length > 0; else noShortLeaveMain\">\r\n <div class=\"w-100 d-flex main-progress-bar justify-content-center align-items-center\" \r\n style=\"background-color: rgb(111, 97, 207); height: 20px; border-radius: 4px; position: relative;\"\r\n (mouseenter)=\"showShortLeaveTooltip($event, row)\"\r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <span class=\"d-block\" [style.min-width.%]=\"row.short_leave[0].short_leave_time_percentage\" \r\n style=\"background-color: rgb(238, 99, 82); height: 100%; border-radius: 4px;\"></span>\r\n <span style=\"position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: white; font-size: 12px; font-weight: bold;\">\r\n {{ row.short_leave[0].short_leave_time_percentage }}%\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-template #noShortLeaveMain>-</ng-template>\r\n</ng-container>\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Attendance Status -->\r\n <ng-container *ngSwitchCase=\"'attendanceStatus'\">\r\n <span class=\"badge\" [class]=\"getAttendanceStatusBadgeClass(getNestedValue(row, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Payroll Processed -->\r\n <ng-container *ngSwitchCase=\"'is_payroll_processed'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Restriction -->\r\n <ng-container *ngSwitchCase=\"'is_un_restricted'\">\r\n <span class=\"badge\" [class]=\"getNestedValue(row, col.field) ? 'badge-success' : 'badge-secondary'\">\r\n {{ getNestedValue(row, col.field) ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{\r\n !isNestedValueArray(row, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(row, col.field))\r\n ? ((getNestedValue(row, col.field)) | timezoneFormat:prefs:'date' )\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-'))\r\n : col.type === 'time'\r\n ? ((getTimeValue(getNestedValue(row, col.field)) | timezoneFormat:prefs:'time'))\r\n : (getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field) ||\r\n '-')\r\n : (getNestedValue(row, col.field)?.[0]?.department_name ||\r\n getNestedValue(row, col.field)?.[0]?.roleName ||\r\n '-')\r\n }}\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"col.type == 'image'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: {\r\n row: row,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Active dot and eye icon for employee name -->\r\n <span *ngIf=\"col.field === 'User' && hasManualLogs(row) && !row.isDetailsExpand\" class=\"badge badge-dot badge-success ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></span>\r\n <i *ngIf=\"col.field === 'User' && hasManualLogs(row)\" class=\"bi bi-eye ms-1\" (mouseenter)=\"showManualLogsTooltip($event, row, row)\"></i>\r\n </div>\r\n\r\n <!-- Expand / Collapse icon for multiple data showing in one coll-->\r\n\r\n <!-- <span\r\n *ngIf=\"\r\n (isOverflowing(cellText) &&\r\n showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50) ||\r\n (isNestedValueArray(row, col.field) &&\r\n getNestedValue(row, col.field)?.length > 1)\r\n \"\r\n class=\"toggle-icon data-grid-svg-icon ms-2 cursor-pointer\"\r\n [inlineSVG]=\"\r\n isExpanded(row, col)\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n toggleExpandOfLongCellText(row, col, columns, true)\r\n \"\r\n (dblclick)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n ></span> -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n fullTextTemplate;\r\n context: {\r\n row: row,\r\n col: col,\r\n isArray: isNestedValueArray(row, col.field)\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n \r\n\r\n\r\n\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<div\r\n *ngIf=\"currentBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentBreakTooltip.break_type?.data_value_name || 'Break' }}</strong>\r\n <span class=\"text-muted ms-2\">\r\n {{ currentBreakTooltip.breakInstatus === 'breakOut' ? 'Taken' : 'On Break' }}\r\n </span>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n In: {{ getTimeValue(currentBreakTooltip.break_in_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n Out: {{ getTimeValue(currentBreakTooltip.break_out_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentBreakTooltip.break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n<!-- Short Break Tooltip -->\r\n<div\r\n *ngIf=\"currentShortBreakTooltip\"\r\n class=\"custom-break-tooltip\"\r\n [style.--tooltip-x.px]=\"tooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"tooltipPosition.y\"\r\n>\r\n <div class=\"break-tooltip-header\">\r\n <strong>{{ currentShortBreakTooltip.short_break_name || 'Short Break' }}</strong>\r\n </div>\r\n\r\n <div class=\"break-tooltip-body\">\r\n <div>\r\n <i class=\"bi bi-play-circle\"></i>\r\n Start: {{ getTimeValue(currentShortBreakTooltip.start_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-stop-circle\"></i>\r\n End: {{ getTimeValue(currentShortBreakTooltip.end_time) | timezoneFormat:prefs:'time' }}\r\n </div>\r\n\r\n <div>\r\n <i class=\"bi bi-clock\"></i>\r\n Duration: {{ currentShortBreakTooltip.short_break_duration }} min\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template #columnMenu let-col=\"col\">\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen && !loading\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showAscending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortAsc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showDescending &&\r\n (sortingConfig?.field != col.field ||\r\n sortingConfig?.order_by == 'asc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDesc(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n sortingConfig?.field === col.field &&\r\n (sortingConfig?.order_by === 'asc' ||\r\n sortingConfig?.order_by === 'desc')\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"resetSort(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n <div class=\"py-2 border-below three-dots-filter\">\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showFilter && !(col.is_search_able === false )\"\r\n class=\"column-menu-item three-dots-filter\"\r\n (click)=\"openFilteronThreeDotsClick(col)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Filter\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateColumnPinInSourceByField(activeCol, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeColumn(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n <!-- Group By -->\r\n <div\r\n *ngIf=\"showRowsGrouping && !(col.is_groupable === false)\"\r\n class=\"column-menu-item\"\r\n (click)=\"groupBy(activeCol)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/diagram-3.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Group by {{ col.header }}\r\n </div>\r\n\r\n <!-- Choose Columns -->\r\n <!-- <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"chooseColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n </div> -->\r\n\r\n <!-- Reset Columns -->\r\n <!-- <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetColumns()\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div> -->\r\n </div>\r\n <div *ngIf=\"isThreeDotsFilterOpen\" class=\"three-dots-col-menu position-relative\" [style.left.px]=\"-140\" >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterMenu; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n<!-- Filter Menue -->\r\n<ng-template #filterMenu let-col=\"col\">\r\n <div\r\n class=\"filter-menu-container filter-menu\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"filter-dropdown-section p-1\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"addFilterDropdownSearch\"\r\n #filterMenueSearchInput\r\n />\r\n\r\n <div class=\"form-check mb-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"isAllSideFilterOptionsSelected(col)\"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n [value]=\"option\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n (change)=\"onOptionToggle(col, option)\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option?.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col.query.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n #filterMenueTextchInput\r\n />\r\n\r\n <ng-container >\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"col.query?.first_value && condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'string' ? 'text' : col.type\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Actions -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Side Menue -->\r\n\r\n<!-- Add this new template for accordion detail column menu -->\r\n<ng-template #detailColumnMenu let-col=\"col\" let-row=\"row\">\r\n <div\r\n class=\"column-menu three-dots-col-menu detail-column-menu\"\r\n [class.visually-hidden]=\"isDetailMenueHidden\"\r\n *ngIf=\"activeDetailCol\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n >\r\n <!-- Sort Ascending -->\r\n <div class=\"border-below pb-2\" [class.disable-sorting]=\"!col.is_sortable\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Sort</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAscending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailAsc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-up.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Ascending\r\n </div>\r\n\r\n <!-- Sort Descending -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showDescending\"\r\n class=\"column-menu-item\"\r\n (click)=\"sortDetailDesc(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-down.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Sort Descending\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.sortOrder\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailSort(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Reset Sort\r\n </div>\r\n </div>\r\n\r\n <div class=\"py-2 border-below\">\r\n <span class=\"muted-text fs-7\" style=\"margin-left: 12px\">Pin</span>\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showPinleft && col?.pinned !== 'left'\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'left')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Left\r\n </div>\r\n\r\n <div\r\n *ngIf=\"\r\n columnThreedotsMunuConfig?.showPinright && col?.pinned !== 'right'\r\n \"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, 'right')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/pin-right.svg'\"\r\n class=\"data-grid-svg-icon data-grid-svg-icon me-2\"\r\n ></span\r\n >Pin Right\r\n </div>\r\n\r\n <div\r\n *ngIf=\"col?.pinned\"\r\n class=\"column-menu-item\"\r\n (click)=\"updateDetailColumnPin(activeDetailCol, row, null)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/layout-three-columns.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Unpin\r\n </div>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeThisColumn\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeDetailColumn(activeDetailCol, row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-expand-vertical.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Autosize This Column\r\n </div>\r\n\r\n <!-- Autosize All Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showAutosizeAllColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"autosizeAllDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrows-angle-expand.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Autosize All Columns\r\n </div>\r\n\r\n\r\n <!-- Choose Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showChoseColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"openDetailChooseColumns(row)\"\r\n>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/ui-checks-grid.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n Choose Columns\r\n</div>\r\n\r\n <!-- Reset Columns -->\r\n <div\r\n *ngIf=\"columnThreedotsMunuConfig?.showResetColumns\"\r\n class=\"column-menu-item\"\r\n (click)=\"resetDetailColumns(row)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/arrow-counterclockwise.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span\r\n >Reset Columns\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Column Pannel / Pivot Mode / Searching -->\r\n\r\n<ng-template #columnPannel>\r\n <div class=\"column-panel-header\">\r\n <!-- Pivot Toggle -->\r\n <div\r\n class=\"form-check form-switch d-flex align-items-center mb-2 pivot-mode px-5 ms-2\"\r\n >\r\n <input\r\n class=\"form-check-input me-2\"\r\n type=\"checkbox\"\r\n id=\"pivotToggle\"\r\n [(ngModel)]=\"pivotMode\"\r\n />\r\n <label class=\"form-check-label\" for=\"pivotToggle\">Pivot Mode</label>\r\n </div>\r\n\r\n <!-- Select All & Search -->\r\n <div class=\"d-flex align-items-center mb-2 px-3\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n\r\n <!-- Separator -->\r\n <hr class=\"my-2\" />\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Right Columns Menue -->\r\n\r\n<!-- Column Panel Item Template -->\r\n<ng-template #columnPanelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expanded\"\r\n (click)=\"col.expanded = !col.expanded\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [id]=\"'group_' + col.header\"\r\n [checked]=\"isColumnVisible(col)\"\r\n (change)=\"toggleGroupVisibility(col)\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'group_' + col.header\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"col.expanded\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"me-2\" style=\"width: 1.5rem\"></span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.is_visible\"\r\n [id]=\"'col_' + col.field\"\r\n (change)=\"onSideMenuColumnsVisibilityChange()\"\r\n />\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center me-2\"\r\n ></span>\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n<!-- Columns Side Filter -->\r\n<ng-template #sideFilters>\r\n <div class=\"py-3 px-2 pe-3 h-100\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n filterAccordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : filterAccordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllFilterAccordions()\"\r\n ></span>\r\n </span>\r\n\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"columnSearch\"\r\n />\r\n </div>\r\n <div\r\n class=\"overflow-auto side-filter-columns-wrapper\"\r\n style=\"height: calc(100% - 120px); scrollbar-width: thin\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : columnSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Apply and Reset Buttons -->\r\n <!-- <div class=\"d-flex gap-2 mt-3 px-2\">\r\n <button\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center flex-fill\"\r\n style=\"height: 32px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterPannelItem let-col=\"col\">\r\n <!-- Group Column -->\r\n <ng-container *ngIf=\"col.children?.length\">\r\n <div class=\"column-group d-flex align-items-center mb-2\">\r\n <!-- Chevron toggle -->\r\n <span class=\"filter-icon-wrapper me-2\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <!-- Group label toggle -->\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"fw-bold text-truncate\"\r\n >{{ col.header }}\r\n <span\r\n class=\"text-primary ms-1\"\r\n *ngIf=\"col?.query?._ids?.length || col?.query?._first_value\"\r\n >*</span\r\n >\r\n </span>\r\n </label>\r\n </div>\r\n\r\n <!-- Children columns -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4\">\r\n <ng-container *ngFor=\"let child of col.children; trackBy: trackByField\">\r\n <ng-container\r\n *ngTemplateOutlet=\"filterPannelItem; context: { col: child }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Leaf Column -->\r\n <ng-container *ngIf=\"!col.children?.length\">\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <span\r\n class=\"me-2 filter-icon-wrapper me-2\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n [class.rotate]=\"col.expandedFilter\"\r\n ></span>\r\n </span>\r\n\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n style=\"cursor: pointer\"\r\n (click)=\"col.expandedFilter = !col.expandedFilter\"\r\n >\r\n <span class=\"text-truncate fw-bold\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n\r\n <!-- Show filter when expanded -->\r\n <div *ngIf=\"col.expandedFilter\" class=\"ps-4 pe-3\">\r\n <ng-container\r\n *ngTemplateOutlet=\"sideNestedFilter; context: { col: col }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Side Nested Filters -->\r\n<ng-template #sideNestedFilter let-col=\"col\">\r\n <div class=\"\">\r\n <!-- Dropdown Type -->\r\n <ng-container *ngIf=\"col.type === 'dropdown'; else textFilter\">\r\n <div class=\"p-1\">\r\n <!-- Search -->\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"col.searchValue\"\r\n />\r\n\r\n <!-- Select All -->\r\n <div class=\"form-check mb-1 ms-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [checked]=\"\r\n col.query?._ids?.length == col?.column_dropdown_value?.length\r\n \"\r\n (change)=\"toggleSelectAllSideFilters(col, $event)\"\r\n id=\"selectAll_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"selectAll_{{ col.field }}\">\r\n Select All\r\n </label>\r\n </div>\r\n\r\n <!-- Options -->\r\n <div class=\"dropdown-options\">\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *ngFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : addFilterDropdownSearch : 'header'\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [value]=\"option\"\r\n [checked]=\"\r\n col.query?._ids?.includes(option?._id || option?.id || option)\r\n \"\r\n (change)=\"onOptionToggle(col, option)\"\r\n id=\"option_{{ col.field }}_{{\r\n option?.id || option?._id || option\r\n }}\"\r\n />\r\n <label\r\n class=\"form-check-label\"\r\n [for]=\"\r\n 'option_' +\r\n col.field +\r\n '_' +\r\n (option?.id || option?._id || option)\r\n \"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <!-- <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"applySideMenuFilters()\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\"\r\n style=\"height: 22px;\"\r\n (click)=\"resetSideMenuFilters()\"\r\n >\r\n Reset\r\n </div>\r\n </div> -->\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Text Filter Section -->\r\n <ng-template #textFilter>\r\n <div class=\"filter-text-section\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query!.first_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query!.first_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptions>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n\r\n <ng-container *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"and\"\r\n id=\"and_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"or\"\r\n id=\"or_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input filter-radio-inputs\"\r\n type=\"radio\"\r\n name=\"condition\"\r\n [(ngModel)]=\"col!.query.condition\"\r\n value=\"none\"\r\n id=\"none_{{ col.field }}\"\r\n />\r\n <label class=\"form-check-label\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [ngModel]=\"col!.query.second_condition || (col.type === 'date' || col.type === 'time' ? 'equal' : 'contain')\"\r\n (ngModelChange)=\"col!.query.second_condition = $event\"\r\n >\r\n <ng-container *ngIf=\"col.type === 'date' || col.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptionsSecond>\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : col.type == 'number' ? 'number' : 'text'\"\r\n class=\"form-control form-control-sm mb-2\"\r\n placeholder=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n [min]=\"col.type == 'number' ? 0 : null\"\r\n (input)=\"col.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"col.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n [class.number-input]=\"col.type == 'number'\"\r\n />\r\n </ng-container>\r\n\r\n <!-- Apply and Reset Buttons -->\r\n <div class=\"d-flex gap-2 mt-2\">\r\n <div\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"applyFilterFromFilterRow(col)\"\r\n >\r\n Apply\r\n </div>\r\n <div\r\n class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 22px\"\r\n (click)=\"resetSideFilter(col)\"\r\n >\r\n Reset\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\" (click)=\"closeModalColumnPanel()\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100\">\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Row Groups</span>\r\n </div>\r\n <div class=\"h-50\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here to set row Groups\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"mt-4\" />\r\n\r\n <div class=\"px-3 h-100\">\r\n <div class=\"d-flex gap-3 mb-4\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/justify.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>Values</span>\r\n </div>\r\n <div class=\"h-50 d-flex\">\r\n <div\r\n class=\"px-3 py-2 border-dashed h-100 d-flex justify-content-center align-items-center\"\r\n style=\"font-size: 14px\"\r\n >\r\n Drag here aggregate\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<!-- Drag Preview Template -->\r\n<!-- *************************************************** -->\r\n<!-- *************************************************** -->\r\n<ng-template #dragPreview let-col>\r\n <div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrows-move.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n <div>{{ col.header }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Drag Placeholder Template -->\r\n<ng-template\r\n #dragPlaceholder\r\n let-col\r\n let-i=\"index\"\r\n let-section=\"section\"\r\n let-draggingInGroupArea=\"draggingInGroupArea\"\r\n>\r\n <div *ngIf=\"!draggingInGroupArea\">\r\n <div\r\n *ngTemplateOutlet=\"\r\n headerCell;\r\n context: { $implicit: col, index: i, section: section }\r\n \"\r\n ></div>\r\n </div>\r\n <div *ngIf=\"draggingInGroupArea\">New Placeholder</div>\r\n</ng-template>\r\n\r\n<!-- Top Group Row Placeholder -->\r\n<ng-template #topGroupingRowPlaceholder let-col let-showChevron=\"showChevron\">\r\n <div class=\"d-flex gap-2\">\r\n <div\r\n class=\"d-flex gap-2 top-row-grouping-placeholder\"\r\n [style.backgroundColor]=\"topGroupedBadgesBackgroundColor\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/grid-3x2-gap.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n <span>{{ col.header }}</span>\r\n <span\r\n (click)=\"ungroupColumn(col)\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"cursor-pointer data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"showChevron\" style=\"opacity: 0.6; font-size: 14px\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #childHeaderPlaceholder\r\n let-col\r\n let-pinnedRight=\"pinnedRight\"\r\n let-i=\"index\"\r\n let-sections=\"sections\"\r\n>\r\n <div\r\n class=\"header-cell one-row-header-cells\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.fontWeight]=\"headerFontWeight\"\r\n >\r\n <div class=\"d-flex justify-content-between h-100 align-items-center w-100\">\r\n <div\r\n class=\"d-flex justify-content-between w-100\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div\r\n class=\"text-ellipsis h-100 d-flex align-items-center\"\r\n [title]=\"col.header\"\r\n [class.w-100]=\"pinnedRight\"\r\n >\r\n {{ col.header }}\r\n </div>\r\n\r\n <div\r\n class=\"position-relative d-flex\"\r\n [class.flex-row-reverse]=\"pinnedRight\"\r\n >\r\n <div class=\"three-dots p-1\" style=\"cursor: pointer\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/three-dots-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n\r\n <div class=\"resize-handle\">\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/resize-handle.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"showFilterRow\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n class=\"header-cell filter-cell\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n style=\"grid-row: 3\"\r\n >\r\n <div\r\n class=\"header-cell filter-cell\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n [style.width.px]=\"col.width\"\r\n [style.min-width.px]=\"col.width\"\r\n [style.height.px]=\"headerRowHeight\"\r\n [style.min-height.px]=\"headerRowHeight\"\r\n [style.max-height.px]=\"headerRowHeight\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter\"\r\n [(ngModel)]=\"col.filterValue\"\r\n />\r\n <span\r\n class=\"filter-icon-wrapper\"\r\n (click)=\"activeFilterCell = col; activeCol = null\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/filter-2.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n\r\n <div\r\n class=\"position-absolute\"\r\n *ngIf=\"activeFilterCell === col\"\r\n style=\"top: 100%; right: 0; z-index: 10; left: 0\"\r\n ></div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tableLayout>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 320px\"\r\n >\r\n <div class=\"d-flex align-items-center mb-3\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Layout</h6>\r\n </div>\r\n <hr class=\"my-2\" />\r\n <div class=\"w-100 mb-3 d-flex\" role=\"group\">\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"small\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'small')\"\r\n [checked]=\"selectedTableLayout == 'small'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"small\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'small' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 8px\"></div>\r\n Small\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"medium\"\r\n autocomplete=\"off\"\r\n [checked]=\"selectedTableLayout == 'medium'\"\r\n (change)=\"changeTableLayout($event, 'medium')\"\r\n />\r\n <label\r\n class=\"border mx-3 d-flex flex-column align-items-center layout-button\"\r\n for=\"medium\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'medium' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 12px\"></div>\r\n Medium\r\n </label>\r\n\r\n <input\r\n type=\"radio\"\r\n class=\"btn-check layout-button-check\"\r\n name=\"layoutSize\"\r\n id=\"large\"\r\n autocomplete=\"off\"\r\n (change)=\"changeTableLayout($event, 'large')\"\r\n [checked]=\"selectedTableLayout == 'large'\"\r\n />\r\n <label\r\n class=\"border d-flex flex-column align-items-center layout-button\"\r\n for=\"large\"\r\n [ngStyle]=\"{\r\n color: selectedTableLayout == 'large' ? '#000' : '#727272'\r\n }\"\r\n >\r\n <div class=\"preview-box border mb-1\" style=\"height: 16px\"></div>\r\n Large\r\n </label>\r\n </div>\r\n\r\n <hr class=\"my-2\" />\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show separators</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"separators\"\r\n [(ngModel)]=\"showVerticalBorder\"\r\n (change)=\"onFontChange()\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <span>Row shading</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"rowShadingEnabled\"\r\n (change)=\"toggleRowShading()\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #tablePreset>\r\n <div\r\n *ngIf=\"activeSubButton !== 'save-preset'\"\r\n (click)=\"$event.stopPropagation();\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Table Presets</h6>\r\n </div>\r\n <!-- Save Preset Button with Dropdown -->\r\n <div>\r\n <a\r\n class=\"text-decoration-none btn btn-link\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n Save Preset\r\n </a>\r\n </div>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n [(ngModel)]=\"searchTextPresetTable\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Preset List -->\r\n <ng-container\r\n *ngIf=\"\r\n tableView | filter : searchTextPresetTable : 'name' as filteredList\r\n \"\r\n >\r\n <!-- If filteredList exists and none is default -> show fallback -->\r\n <div class=\"\" (click)=\"selectDefault()\">\r\n <div class=\"fw-semibold\">Default View\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"tableFilterViewId === 'default'\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n >\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end\">\r\n <a\r\n (click)=\"actionPreset({ id: 'default' }, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/star.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n </ul>\r\n </div>\r\n </div>\r\n\r\n <!-- The list: render each table from filteredList -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n *ngFor=\"let table of filteredList; trackBy: trackByTable\"\r\n >\r\n <!-- Item -->\r\n <div\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table)\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer;\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"table?.is_temp\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n </div>\r\n <small class=\"text-dark\"\r\n >Created {{ table?.createdAt | timezoneFormat:prefs:'date' }}</small\r\n >\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_deafult\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n\r\n <div class=\"dropdown\" *ngIf=\"!table?.is_deafult\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n class=\"muted-text\"\r\n data-bs-toggle=\"dropdown\"\r\n id=\"dropdownMenuButton2\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </a>\r\n <ul class=\"dropdown-menu dropdown-menu-end set-default-preset\" aria-labelledby=\"dropdownMenuButton2\">\r\n <a\r\n [class.d-none]=\"confirmDelete\"\r\n (click)=\"actionPreset(table, 'setPreset')\"\r\n class=\"dropdown-item d-flex align-items-center\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/star.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Set as default\r\n </a>\r\n\r\n <!-- Delete with confirmation -->\r\n <ng-container *ngIf=\"!confirmDelete; else confirmBlock\">\r\n <a\r\n (click)=\"confirmDelete = true\"\r\n class=\"dropdown-item d-flex align-items-center text-danger\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Confirmation block -->\r\n </ul>\r\n <ng-template #confirmBlock>\r\n <div class=\"dropdown-item\"><b>Delete preset</b></div>\r\n <div class=\"dropdown-item text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete the <br />\r\n <b>\u201C{{ table?.name }}\u201D</b> preset?\r\n </div>\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger delete-preset\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"confirm-preset-delete\"\r\n ></span>\r\n Delete\r\n </button>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"activeSubButton == 'save-preset'\"\r\n class=\"dropdown-menu p-3 badge mt-4 save-preset-dropdown mt-1\"\r\n aria-labelledby=\"savePresetDropdown\"\r\n style=\"min-width: 250px\"\r\n >\r\n <div class=\"fw-bold fs-14px mb-2\">Save preset</div>\r\n <div class=\"fs-14px mb-2\" style=\"line-height: 20px\">\r\n This will save the current table adjustments as a preset.\r\n </div>\r\n <!-- Input -->\r\n <div class=\"mb-2\">\r\n <label for=\"presetName\" class=\"form-label fs-12px fw-bold\"\r\n >Preset Name</label\r\n >\r\n <div class=\"col-12 global-search\">\r\n <input\r\n #presetNameCtrl=\"ngModel\"\r\n required\r\n [(ngModel)]=\"presetName\"\r\n [ngClass]=\"{\r\n 'is-invalid':\r\n presetNameCtrl.invalid &&\r\n (presetNameCtrl.dirty || presetNameCtrl.touched)\r\n }\"\r\n class=\"form-control form-control-sm ps-2\"\r\n placeholder=\"Enter preset name\"\r\n type=\"text\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- Checkbox -->\r\n <div class=\"form-check mb-2\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"presetFilter\"\r\n type=\"checkbox\"\r\n id=\"saveFilters\"\r\n />\r\n <label class=\"form-check-label mt-1\" for=\"saveFilters\">\r\n Save active filters\r\n </label>\r\n </div>\r\n\r\n <!-- Save Button -->\r\n <div class=\"d-flex justify-content-center gap-2\" style=\"height: 32px\">\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn border w-100 d-flex align-items-center justify-content-center btn-light\"\r\n (click)=\"$event.stopPropagation(); toggleActions('table-presets')\"\r\n style=\"margin-top: -2px\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n [disabled]=\"closeDropdown.preset.loading\"\r\n (click)=\"savePreset(presetNameCtrl)\"\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center\"\r\n >\r\n <span style=\"margin-top: -2px\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && (!tableFilterViewId || tableFilterViewId === 'default')\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading && tableFilterViewId && tableFilterViewId !== 'default'\"\r\n >Update</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #showHideColumns>\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"p-3 shadow rounded-3 bg-white actions-dropdown mt-1 dropdown-menu show shadow custom-menu table-layout\"\r\n style=\"width: 280px\"\r\n >\r\n <!-- Header -->\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <button\r\n class=\"btn btn-link p-0\"\r\n style=\"margin-left: -10px\"\r\n (click)=\"toggleActions('setting')\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon\"\r\n ></span>\r\n </button>\r\n <h6 class=\"mb-0 ms-2\" style=\"font-weight: 500\">Columns</h6>\r\n </div>\r\n <a\r\n (click)=\"resetColumns()\"\r\n href=\"javascript:void(0)\"\r\n class=\"text-primary text-decoration-none\"\r\n >Reset</a\r\n >\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"mb-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"mx-2 position-absolute icon data-grid-svg-icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search column\"\r\n type=\"search\"\r\n [(ngModel)]=\"topShowHideColumns\"\r\n />\r\n </div>\r\n </div>\r\n <!-- Preset List -->\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"\r\n max-height: calc(100vh - 300px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n \"\r\n >\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyVisibleColumn\">\r\n Show in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"show_hide_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label for=\"show_hide_all\" class=\"form-check-label fw-semibold\">Show/Hide All</label>\r\n </div>\r\n </div>\r\n <!-- <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryVisible()\"\r\n (change)=\"toggleAllVisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Show All</label>\r\n </div> -->\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length && !isMandatory(col)\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"(!col?.query?.first_value && !col?.query?._ids?.length && isMandatory(col)) || (col?.query?.first_value || col?.query?._ids?.length)\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <!-- <div\r\n class=\"muted-text show-hide-table-label\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n </div>\r\n <div class=\"d-flex align-items-center mb-2\" *ngIf=\"hasAnyInVisibleColumn\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\">Hide All</label>\r\n </div> -->\r\n\r\n \r\n\r\n\r\n\r\n <div class=\"muted-text show-hide-table-label d-flex justify-content-between\" *ngIf=\"hasAnyInVisibleColumn\">\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"hide_show_all\"\r\n class=\"form-check-input\"\r\n [checked]=\"areAllNonMandatoryHidden()\"\r\n (change)=\"toggleAllInvisibleColumns()\"\r\n />\r\n <label for=\"hide_show_all\" class=\"form-check-label fw-semibold\">Hide/Show All</label>\r\n </div>\r\n </div>\r\n <div class=\"list-group list-group-flush\">\r\n <ng-container *ngFor=\"let col of columns; trackBy: trackByField\">\r\n <div\r\n *ngIf=\"!col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"data-grid-svg-icon cursor-grap\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, true)\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #filterColumns let-col=\"column\">\r\n <div\r\n @slideToggle\r\n *ngIf=\"!isFilterOpen && activeTopButton == 'filter-columns'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"mb-2 px-3\">\r\n <div class=\"col-12 global-search\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/search.svg'\"\r\n class=\"data-grid-svg-icon mx-2 position-absolute icon\"\r\n ></span>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Filter by\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 500px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : addFilterColumnInput : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n (click)=\"openFilter(col)\"\r\n *ngIf=\"\r\n col.is_visible &&\r\n !col?.query?.first_value &&\r\n !col?.query?._ids?.length\r\n \"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div style=\"margin-top: -3px\"></div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div\r\n @slideToggle\r\n *ngIf=\"isFilterOpen && selectedColumnForFilter.type == 'dropdown'\"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions!.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n (ngModelChange)=\"selectedFilterOptions.length === 0 ? condition = 'none' : null\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow rounded-3 bg-white actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n >\r\n <div class=\"px-3 border-below py-1 pb-2 d-flex ps-1\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"col-12 position-relative p-2 text-filter\">\r\n <div class=\"mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptions\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptions>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (ngModelChange)=\"!firstValue ? condition = 'none' : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n <div class=\"d-flex my-3\">\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalAnd\"\r\n name=\"logicalOperator\"\r\n value=\"and\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalAnd\">AND</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalOr\"\r\n name=\"logicalOperator\"\r\n value=\"or\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div class=\"form-check form-check-inline\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"radio\"\r\n id=\"logicalNone\"\r\n name=\"logicalOperator\"\r\n value=\"none\"\r\n [(ngModel)]=\"condition\"\r\n />\r\n <label class=\"form-check-label\" for=\"logicalNone\">None</label>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"firstValue && condition !== 'none'\">\r\n <div class=\"my-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type === 'date' || selectedColumnForFilter.type === 'time'; else textOptionsSecond\">\r\n <option value=\"equal\">Equal to</option>\r\n <option value=\"not_equal\">Not Equal</option>\r\n <option value=\"after\">After</option>\r\n <option value=\"before\">Before</option>\r\n </ng-container>\r\n <ng-template #textOptionsSecond>\r\n <option value=\"equal\">Equals</option>\r\n <!-- <option value=\"not_equal\">Not Equals</option> -->\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"before\">Begins With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-template>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n [(ngModel)]=\"secondValue\"\r\n [min]=\"selectedColumnForFilter.type == 'number' ? 0 : null\"\r\n [class.number-input]=\"selectedColumnForFilter.type == 'number'\"\r\n (input)=\"selectedColumnForFilter.type == 'number' && $any($event.target).value < 0 ? $any($event.target).value = 0 : null\"\r\n (keydown)=\"selectedColumnForFilter.type == 'number' && $event.key === '-' ? $event.preventDefault() : null\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetTextFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Edit dropdown here -->\r\n<ng-template let-col>\r\n <div class=\"drop-down-edit\"></div>\r\n</ng-template>\r\n\r\n<ng-template\r\n #fullTextTemplate\r\n let-row=\"row\"\r\n let-col=\"col\"\r\n let-isArray=\"isArray\"\r\n>\r\n <div\r\n class=\"full-text-box\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault();\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n <ng-container *ngIf=\"!isEditing(row, col)\">\r\n <div\r\n *ngIf=\"!isArray\"\r\n class=\"full-text-content\"\r\n (dblclick)=\"$event.stopPropagation(); $event.preventDefault(); enableEdit(row, col)\"\r\n (click)=\"$event.stopPropagation(); $event.preventDefault()\"\r\n >\r\n {{\r\n getNestedValue(row, col.field)?.value ||\r\n getNestedValue(row, col.field)?.name ||\r\n getNestedValue(row, col.field)\r\n }}\r\n </div>\r\n <div *ngIf=\"isArray\">\r\n <ul>\r\n <ng-container\r\n *ngFor=\"let item of getNestedValue(row, col.field); let i = index\"\r\n >\r\n <li *ngIf=\"i !== 0\">\r\n <ng-container>\r\n {{ item?.department_name || item?.roleName || \"-\" }}\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"isEditing(row, col)\">\r\n <textarea\r\n #textModel=\"ngModel\"\r\n rows=\"4\"\r\n #textAreadInput\r\n [(ngModel)]=\"row[col.field]\"\r\n name=\"{{ col.field }}\"\r\n required\r\n (blur)=\"disableEdit(row, col, textModel)\"\r\n (keydown.enter)=\"textAreadInput.blur()\"\r\n autofocus\r\n class=\"form-control\"\r\n [ngClass]=\"{\r\n 'is-invalid': textModel.invalid\r\n }\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n ></textarea>\r\n\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultImagePlaceholder let-row=\"row\" let-col=\"col\">\r\n <span\r\n class=\"px-2 d-flex align-items-center w-100 cell-content image-placeholder cursor-pointer position-relative\"\r\n [title]=\"getEmployeeNameTitle(row)\"\r\n (click)=\"onEmployeeClick(row)\"\r\n >\r\n <!-- Blue dot for manual logs -->\r\n <span\r\n *ngIf=\"row?.manually_logs && row.manually_logs.length > 0\"\r\n class=\"manual-logs-indicator\"\r\n (mouseenter)=\"openManualLogsModal($event, row)\"\r\n (mouseleave)=\"closeManualLogsModal()\"\r\n ></span>\r\n <ng-container\r\n *ngIf=\"\r\n row?.User?.logo || row?.User?.profile_pictures?.length || row?.logo || row?.profile_pictures?.length || row?.assetImage || row?.invoice?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span class=\"pic\">\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [src]=\"row?.User?.profile_pictures?.[4]?.path || row?.User?.logo || row?.profile_pictures?.[4]?.path || row?.logo || row?.assetImage || row?.invoice?.invoice_image\"\r\n alt=\"icon\"\r\n />\r\n </span>\r\n </ng-container>\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(row?.User?.full_name || row?.full_name || row?.name)\"\r\n class=\"pic d-flex align-items-center rounded-circle\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n [style.fontSize.px]=\"rowHeight / 3\"\r\n >\r\n {{ getInitials(row?.User?.full_name || row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\r\n</ng-template>\r\n\r\n<!-- Cell Content Template for Card View -->\r\n<ng-template #cellContent let-row=\"row\" let-parentRow=\"parentRow\" let-col=\"col\">\r\n <ng-container [ngSwitch]=\"col.type\">\r\n <!-- String/Text -->\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Number -->\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n\r\n <!-- Date -->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) ? (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) | timezoneFormat:prefs:'date') : '-' }}\r\n </ng-container>\r\n\r\n <!-- Time -->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== null && (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) !== undefined ? ((getTimeValue(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) | timezoneFormat:prefs:'time')) : '-' }}\r\n </ng-container>\r\n\r\n <!-- Boolean -->\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <span class=\"badge\" [class]=\"(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'badge-success' : 'badge-secondary'\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === true || getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) === 'true') ? 'Yes' : 'No' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- <div *ngSwitchCase=\"'is_payroll_processed'\" class=\"d-flex justify-content-start flex-column pointer position-relative\" >\r\n <span class=\"popover__wrapper\" >none\r\n {{ row.is_payroll_processed ? 'Yes' : 'No' }}\r\n </span>\r\n </div> -->\r\n\r\n <!-- Status -->\r\n <ng-container *ngSwitchCase=\"'status'\">\r\n <span class=\"badge\" [class]=\"getStatusBadgeClass(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ transformStatus(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field)) || '-' }}\r\n </span>\r\n </ng-container>\r\n\r\n <!-- Array -->\r\n <ng-container *ngSwitchCase=\"'array'\">\r\n <ng-container *ngIf=\"isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n <ng-container *ngIf=\"col.field === 'breaks' || col.header?.toLowerCase().includes('break')\">\r\n <app-badge-overflow\r\n [badges]=\"getBreakBadges(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || [])\"\r\n [maxWidth]=\"col.width || 200\"\r\n (badgeMouseEnter)=\"showBreakTooltip($event.event, $event.badge.data)\"\r\n (badgeMouseLeave)=\"hideBreakTooltip()\"\r\n (overflowCountClick)=\"onBadgeOverflowCountClick(col)\">\r\n </app-badge-overflow>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(col.field === 'breaks' || col.header?.toLowerCase().includes('break'))\">\r\n {{ (getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || []).length }} items\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isArray(getNestedValue(row, col.field) || getNestedValue(parentRow, col.field))\">\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Default -->\r\n <ng-container *ngSwitchDefault>\r\n {{ getNestedValue(row, col.field) || getNestedValue(parentRow, col.field) || '-' }}\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Right Click Menue -->\r\n<div\r\n [class.invisible]=\"!positionedYet\"\r\n class=\"context-menu p-2\"\r\n *ngIf=\"actionHide && actions?.length\"\r\n [ngStyle]=\"{ 'top.px': yPos, 'left.px': xPos }\"\r\n [class.show]=\"isVisible\"\r\n appendTo=\"body\"\r\n>\r\n <ul>\r\n <li\r\n *ngFor=\"let action of actions\"\r\n class=\"rounded d-flex align-items-center\"\r\n (click)=\"onActionClick(action)\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/' + action + '.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n <span class=\"text-capitalize fw-500\">{{ action }}</span>\r\n </li>\r\n </ul>\r\n</div>\r\n\r\n<!-- Details Toggle from bottom -->\r\n<div\r\n [style.bottom.px]=\"footerRowHeight + 50\"\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar\"\r\n>\r\n <div class=\"selected-rows-action-bar\" [@slideUp]>\r\n <span class=\"selected-count\">\r\n {{ selectedRows.size }} selected of\r\n {{ config?.paginationParams?.totalItems }} Total\r\n </span>\r\n <div class=\"action-buttons\">\r\n <ng-container *ngFor=\"let action of taskbarActions; let i = index\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"action === 'Export' ? onExportClick() : action === 'Delete' ? onDeleteClick() : onVerifyClick(action)\"\r\n >{{ action }}</span\r\n >\r\n <span\r\n *ngIf=\"taskbarActions.length > 1 && i !== taskbarActions.length - 1\"\r\n class=\"separator\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Detail Row Choose Columns Modal -->\r\n<div *ngIf=\"showDetailColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"detailModalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Short Leave Tooltip Modal -->\r\n<div *ngIf=\"showShortLeaveTooltipModal\" \r\n class=\"custom-break-tooltips\" \r\n [style.--tooltip-x.px]=\"shortLeaveTooltipPosition.x\" \r\n [style.--tooltip-y.px]=\"shortLeaveTooltipPosition.y\"\r\n (mouseenter)=\"preventShortLeaveTooltipHide()\" \r\n (mouseleave)=\"hideShortLeaveTooltip()\">\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Leave Type</th>\r\n <th>Start Time</th>\r\n <th>End Time</th>\r\n <th>Duration (min)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of currentShortLeaveData\">\r\n <td>{{ item.leave_type || 'N/A' }}</td>\r\n <td>{{ item.star_time || 'N/A' }}</td>\r\n <td>{{ item.end_time || 'N/A' }}</td>\r\n <td>{{ item.minutes || 'N/A' }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Tooltip for accordion manual logs -->\r\n<!-- Tooltip for accordion manual logs -->\r\n<div *ngIf=\"showManualLogsTooltipModal\" class=\"custom-break-tooltips\"\r\n [style.--tooltip-x.px]=\"manualLogsTooltipPosition.x\"\r\n [style.--tooltip-y.px]=\"manualLogsTooltipPosition.y\"\r\n (mouseenter)=\"preventManualLogsTooltipHide()\"\r\n (mouseleave)=\"hideManualLogsTooltip()\">\r\n\r\n <div class=\"modal-body\">\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-striped text-dark\">\r\n <thead>\r\n <tr>\r\n <th>Name</th>\r\n <th>Date/Time</th>\r\n <th>Previous</th>\r\n <th>Updated</th>\r\n <th>Status</th>\r\n <th>Remarks</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of selectedManualLogs; let i = index\">\r\n <tr>\r\n <td>{{ item?.updated_by?.full_name || selectedManualLogsRow?.User?.full_name }}</td>\r\n <td>{{ item?.log_date && item.log_date !== '--' ? (item.log_date | timezoneFormat:prefs:'date') : (selectedManualLogsRow?.attendanceDate && selectedManualLogsRow?.attendanceDate !== '--' ? (selectedManualLogsRow?.attendanceDate | timezoneFormat:prefs:'date') : '-') }}</td>\r\n <td>{{ formatLogState(item?.log_details?.previous_state) }}</td>\r\n <td>{{ formatLogState(item?.log_details?.updated_state) }}</td>\r\n <td>{{ item?.log_details?.status ? transformStatus(item.log_details.status) : (item.log_details?.status || '-') }}</td>\r\n <td>{{ item?.log_details?.remarks || item?.remarks || selectedManualLogsRow?.message || '-' }}</td>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Fallback for empty manual logs -->\r\n <tr *ngIf=\"!selectedManualLogs || selectedManualLogs.length === 0\">\r\n <td colspan=\"6\" class=\"text-center\">No manual logs available</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n </div>\r\n<!-- </div> -->\r\n\r\n<ng-template #detailModalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Detail Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeDetailColumnPanel()\">\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span>\r\n </span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allDetailColumnsSelected()\"\r\n (change)=\"toggleAllDetailColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search detail columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of (currentDetailRowForColumnSelection?.details?.columns || [])\r\n | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div class=\"d-flex align-items-center mb-2\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"col.is_visible !== false\"\r\n (change)=\"toggleDetailColumnVisibility(col, !col.is_visible)\"\r\n [id]=\"'detail_col_' + col.field\"\r\n />\r\n <label\r\n class=\"d-flex align-items-center mb-0 w-100\"\r\n [for]=\"'detail_col_' + col.field\"\r\n style=\"cursor: pointer\"\r\n >\r\n <span class=\"text-truncate\">{{ col.header }}</span>\r\n </label>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- <div class=\"px-3 py-2 border-top d-flex justify-content-end\">\r\n <button class=\"btn btn-sm btn-link\" (click)=\"resetDetailColumnsInModal()\">Reset</button>\r\n </div> -->\r\n </div>\r\n</ng-template>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: ["@charset \"UTF-8\";@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.02)}to{transform:scale(1)}}@keyframes shimmer{0%{background-position:-200px 0}to{background-position:calc(200px + 100%) 0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-overlay{animation:fadeInScale .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.loading-overlay .spinner-border{animation:spin 1s linear infinite}.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;box-shadow:none!important;position:relative;animation:fadeInScale .35s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.data-grid-table-wrapper[data-theme=white]{border-color:#d9d9db;background-color:#f6f8ff;color:#000}.data-grid-table-wrapper[data-theme=white] *,.data-grid-table-wrapper[data-theme=white] *:before,.data-grid-table-wrapper[data-theme=white] *:after{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-moz-selection{background-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-header-wrapper{background-color:#f8f9fa;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-body-wrapper{background-color:#f6f8ff;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row{border-bottom-color:#d9d9db;box-shadow:none!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .data-grid-row:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .selected-cell,.data-grid-table-wrapper[data-theme=white] .row-selected{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .cell,.data-grid-table-wrapper[data-theme=white] .header-cell,.data-grid-table-wrapper[data-theme=white] .data-grid-row,.data-grid-table-wrapper[data-theme=white] .data-grid-header,.data-grid-table-wrapper[data-theme=white] .cell-content,.data-grid-table-wrapper[data-theme=white] .full-text-content,.data-grid-table-wrapper[data-theme=white] .circle-value,.data-grid-table-wrapper[data-theme=white] .pic,.data-grid-table-wrapper[data-theme=white] .image-placeholder,.data-grid-table-wrapper[data-theme=white] .s-no,.data-grid-table-wrapper[data-theme=white] .fw-500{color:#000!important}.data-grid-table-wrapper[data-theme=white] span,.data-grid-table-wrapper[data-theme=white] div,.data-grid-table-wrapper[data-theme=white] p,.data-grid-table-wrapper[data-theme=white] td,.data-grid-table-wrapper[data-theme=white] th,.data-grid-table-wrapper[data-theme=white] label,.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#000!important}.data-grid-table-wrapper[data-theme=white] svg,.data-grid-table-wrapper[data-theme=white] svg path,.data-grid-table-wrapper[data-theme=white] svg circle,.data-grid-table-wrapper[data-theme=white] svg rect,.data-grid-table-wrapper[data-theme=white] svg polygon{color:#000!important;fill:#000!important;stroke:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon{color:#000!important}.data-grid-table-wrapper[data-theme=white] .data-grid-svg-icon path{stroke:#000!important;fill:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-danger{background-color:#ea5353!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-success{background-color:#84ca81!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-warning{background-color:#fff3dc!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .badge.badge-info{background-color:#e8fbfd!important;color:#00bad1!important}.data-grid-table-wrapper[data-theme=white] .context-menu{background:#f6f8ff;border-color:#d9d9db;color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li{color:#000!important}.data-grid-table-wrapper[data-theme=white] .context-menu li:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .custom-tooltip,.data-grid-table-wrapper[data-theme=white] .popover__content,.data-grid-table-wrapper[data-theme=white] .custom-break-tooltip{background:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown,.data-grid-table-wrapper[data-theme=white] .custom-menu{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item{color:#000!important}.data-grid-table-wrapper[data-theme=white] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=white] .custom-menu .dropdown-item:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar{background-color:#343a40!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr{color:#000!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] .manual-logs-modal .modal-body .table tbody tr td{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .form-control,.data-grid-table-wrapper[data-theme=white] .form-select{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .form-control::placeholder,.data-grid-table-wrapper[data-theme=white] .form-select::placeholder{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .form-control option,.data-grid-table-wrapper[data-theme=white] .form-select option{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .active-filters{background-color:#f8f9fa!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .custom-modal-overlay .custom-modal-content{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .circle-value{background-color:#f8f9fa!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container,.data-grid-table-wrapper[data-theme=white] .page-size,.data-grid-table-wrapper[data-theme=white] .page-info,.data-grid-table-wrapper[data-theme=white] .page-buttons{color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container select,.data-grid-table-wrapper[data-theme=white] .pagination-container button,.data-grid-table-wrapper[data-theme=white] .pagination-container span,.data-grid-table-wrapper[data-theme=white] .page-size select,.data-grid-table-wrapper[data-theme=white] .page-size button,.data-grid-table-wrapper[data-theme=white] .page-size span,.data-grid-table-wrapper[data-theme=white] .page-info select,.data-grid-table-wrapper[data-theme=white] .page-info button,.data-grid-table-wrapper[data-theme=white] .page-info span,.data-grid-table-wrapper[data-theme=white] .page-buttons select,.data-grid-table-wrapper[data-theme=white] .page-buttons button,.data-grid-table-wrapper[data-theme=white] .page-buttons span{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .pagination-container button.active,.data-grid-table-wrapper[data-theme=white] .page-size button.active,.data-grid-table-wrapper[data-theme=white] .page-info button.active,.data-grid-table-wrapper[data-theme=white] .page-buttons button.active{background-color:#e3f2fd!important}.data-grid-table-wrapper[data-theme=white] .footer-row{background-color:#f8f9fa!important;border-top-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb{background-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-thumb:hover{background-color:#adb5bd!important}.data-grid-table-wrapper[data-theme=white] ::-webkit-scrollbar-track{background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#343a40,#495057)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th{color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.is-other-month{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th.active{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th span.in-range{background-color:#e3f2fd!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f8f9fa!important;border-top-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#f6f8ff!important;border-color:#007bff!important}.data-grid-table-wrapper[data-theme=white] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f6f8ff!important;color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] button,.data-grid-table-wrapper[data-theme=white] .btn,.data-grid-table-wrapper[data-theme=white] .button{background-color:#f6f8ff!important;border-color:#d9d9db!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] button:hover,.data-grid-table-wrapper[data-theme=white] .btn:hover,.data-grid-table-wrapper[data-theme=white] .button:hover{background-color:#007bff1a!important}.data-grid-table-wrapper[data-theme=white] button.btn-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-primary{background-color:#007bff!important;border-color:#007bff!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=white] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=white] .button.btn-outline-primary{border-color:#007bff!important;color:#007bff!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary){color:#007bff!important}.data-grid-table-wrapper[data-theme=white] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=white] .text-primary{color:#007bff!important}.data-grid-table-wrapper[data-theme=white] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=white] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=white] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=white] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=white] .text-muted,.data-grid-table-wrapper[data-theme=white] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=white] .border,.data-grid-table-wrapper[data-theme=white] .border-top,.data-grid-table-wrapper[data-theme=white] .border-bottom,.data-grid-table-wrapper[data-theme=white] .border-left,.data-grid-table-wrapper[data-theme=white] .border-right,.data-grid-table-wrapper[data-theme=white] .border-below,.data-grid-table-wrapper[data-theme=white] .border-start,.data-grid-table-wrapper[data-theme=white] .border-end{border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=white] .accordion-details,.data-grid-table-wrapper[data-theme=white] .nested-table,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll{background-color:#f6f8ff!important;color:#000!important}.data-grid-table-wrapper[data-theme=white] .accordion-details td,.data-grid-table-wrapper[data-theme=white] .accordion-details th,.data-grid-table-wrapper[data-theme=white] .nested-table td,.data-grid-table-wrapper[data-theme=white] .nested-table th,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=white] .detail-virtual-scroll th{color:#000!important;border-color:#d9d9db!important}.data-grid-table-wrapper[data-theme=blue]{border-color:#b3d9ff;background-color:#f0f8ff;color:#1e3a5f}.data-grid-table-wrapper[data-theme=blue] *,.data-grid-table-wrapper[data-theme=blue] *:before,.data-grid-table-wrapper[data-theme=blue] *:after{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-moz-selection{background-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-header-wrapper{background-color:#e6f3ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-body-wrapper{background-color:#f0f8ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row{border-bottom-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:nth-child(odd){background-color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-row:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .selected-cell,.data-grid-table-wrapper[data-theme=blue] .row-selected{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .cell,.data-grid-table-wrapper[data-theme=blue] .header-cell,.data-grid-table-wrapper[data-theme=blue] .data-grid-row,.data-grid-table-wrapper[data-theme=blue] .data-grid-header,.data-grid-table-wrapper[data-theme=blue] .cell-content,.data-grid-table-wrapper[data-theme=blue] .full-text-content,.data-grid-table-wrapper[data-theme=blue] .circle-value,.data-grid-table-wrapper[data-theme=blue] .pic,.data-grid-table-wrapper[data-theme=blue] .image-placeholder,.data-grid-table-wrapper[data-theme=blue] .s-no,.data-grid-table-wrapper[data-theme=blue] .fw-500{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] span,.data-grid-table-wrapper[data-theme=blue] div,.data-grid-table-wrapper[data-theme=blue] p,.data-grid-table-wrapper[data-theme=blue] td,.data-grid-table-wrapper[data-theme=blue] th,.data-grid-table-wrapper[data-theme=blue] label,.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] svg,.data-grid-table-wrapper[data-theme=blue] svg path,.data-grid-table-wrapper[data-theme=blue] svg circle,.data-grid-table-wrapper[data-theme=blue] svg rect,.data-grid-table-wrapper[data-theme=blue] svg polygon{color:#1e3a5f!important;fill:#1e3a5f!important;stroke:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .data-grid-svg-icon path{stroke:#1e3a5f!important;fill:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-danger{background-color:#ff8787!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-success{background-color:#69db7c!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-warning{background-color:#ffd43b!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .badge.badge-info{background-color:#74c0fc!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .context-menu{background:#e6f3ff;border-color:#b3d9ff;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .context-menu li:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .custom-tooltip,.data-grid-table-wrapper[data-theme=blue] .popover__content,.data-grid-table-wrapper[data-theme=blue] .custom-break-tooltip{background:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown,.data-grid-table-wrapper[data-theme=blue] .custom-menu{background-color:#e6f3ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .actions-dropdown .dropdown-item:hover,.data-grid-table-wrapper[data-theme=blue] .custom-menu .dropdown-item:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar{background-color:#1e3a5f!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .taskbar .selected-rows-action-bar .action-btn{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-header .modal-title{color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table thead th{background:linear-gradient(135deg,#e6f3ff,#cce5ff)!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:nth-child(2n){background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] .manual-logs-modal .modal-body .table tbody tr td{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .form-control,.data-grid-table-wrapper[data-theme=blue] .form-select{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .form-control::placeholder,.data-grid-table-wrapper[data-theme=blue] .form-select::placeholder{color:#888!important}.data-grid-table-wrapper[data-theme=blue] .form-control option,.data-grid-table-wrapper[data-theme=blue] .form-select option{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt{background-color:#f6f8ff!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .filter-serach-inpt input{background-color:#f6f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .active-filters,.data-grid-table-wrapper[data-theme=blue] .custom-modal-overlay .custom-modal-content{background-color:#e6f3ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .circle-value{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container,.data-grid-table-wrapper[data-theme=blue] .page-size,.data-grid-table-wrapper[data-theme=blue] .page-info,.data-grid-table-wrapper[data-theme=blue] .page-buttons{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container select,.data-grid-table-wrapper[data-theme=blue] .pagination-container button,.data-grid-table-wrapper[data-theme=blue] .pagination-container span,.data-grid-table-wrapper[data-theme=blue] .page-size select,.data-grid-table-wrapper[data-theme=blue] .page-size button,.data-grid-table-wrapper[data-theme=blue] .page-size span,.data-grid-table-wrapper[data-theme=blue] .page-info select,.data-grid-table-wrapper[data-theme=blue] .page-info button,.data-grid-table-wrapper[data-theme=blue] .page-info span,.data-grid-table-wrapper[data-theme=blue] .page-buttons select,.data-grid-table-wrapper[data-theme=blue] .page-buttons button,.data-grid-table-wrapper[data-theme=blue] .page-buttons span{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .pagination-container button.active,.data-grid-table-wrapper[data-theme=blue] .page-size button.active,.data-grid-table-wrapper[data-theme=blue] .page-info button.active,.data-grid-table-wrapper[data-theme=blue] .page-buttons button.active{background-color:#cce5ff!important}.data-grid-table-wrapper[data-theme=blue] .footer-row{background-color:#e6f3ff!important;border-top-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb{background-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-thumb:hover{background-color:#74c0fc!important}.data-grid-table-wrapper[data-theme=blue] ::-webkit-scrollbar-track{background-color:#f0f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker{background-color:#e6f3ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-head{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-body{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th{color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.is-other-month,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.is-other-month{color:#888!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td.active,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th.active{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td span.in-range,.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th span.in-range{background-color:#cce5ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table td:hover:not(.active),.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker table th:hover:not(.active){background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons{background-color:#f6f8ff!important;border-top-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:linear-gradient(135deg,#1e3a5f,#2d4a6b)!important;color:#f6f8ff!important;border-color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] ::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background-color:#f0f8ff!important;color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] button,.data-grid-table-wrapper[data-theme=blue] .btn,.data-grid-table-wrapper[data-theme=blue] .button{background-color:#f6f8ff!important;border-color:#b3d9ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] button:hover,.data-grid-table-wrapper[data-theme=blue] .btn:hover,.data-grid-table-wrapper[data-theme=blue] .button:hover{background-color:#1e3a5f1a!important}.data-grid-table-wrapper[data-theme=blue] button.btn-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-primary{background-color:#007cf5!important;border-color:#007cf5!important;color:#f6f8ff!important}.data-grid-table-wrapper[data-theme=blue] button.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .btn.btn-outline-primary,.data-grid-table-wrapper[data-theme=blue] .button.btn-outline-primary{border-color:#007cf5!important;color:#007cf5!important;background-color:transparent!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary){color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] a:not(.text-primary):hover{color:#0056b3!important}.data-grid-table-wrapper[data-theme=blue] .text-primary{color:#007cf5!important}.data-grid-table-wrapper[data-theme=blue] .text-danger{color:#dc3545!important}.data-grid-table-wrapper[data-theme=blue] .text-success{color:#28a745!important}.data-grid-table-wrapper[data-theme=blue] .text-warning{color:#ffc107!important}.data-grid-table-wrapper[data-theme=blue] .text-info{color:#17a2b8!important}.data-grid-table-wrapper[data-theme=blue] .text-muted,.data-grid-table-wrapper[data-theme=blue] .muted-text{color:#6c757d!important}.data-grid-table-wrapper[data-theme=blue] .border,.data-grid-table-wrapper[data-theme=blue] .border-top,.data-grid-table-wrapper[data-theme=blue] .border-bottom,.data-grid-table-wrapper[data-theme=blue] .border-left,.data-grid-table-wrapper[data-theme=blue] .border-right,.data-grid-table-wrapper[data-theme=blue] .border-below,.data-grid-table-wrapper[data-theme=blue] .border-start,.data-grid-table-wrapper[data-theme=blue] .border-end{border-color:#b3d9ff!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details,.data-grid-table-wrapper[data-theme=blue] .nested-table,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll{background-color:#f0f8ff!important;color:#1e3a5f!important}.data-grid-table-wrapper[data-theme=blue] .accordion-details td,.data-grid-table-wrapper[data-theme=blue] .accordion-details th,.data-grid-table-wrapper[data-theme=blue] .nested-table td,.data-grid-table-wrapper[data-theme=blue] .nested-table th,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll td,.data-grid-table-wrapper[data-theme=blue] .detail-virtual-scroll th{color:#1e3a5f!important;border-color:#b3d9ff!important}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:30px}.header-cell .filter-applied-on-text{color:#5d9cff!important}.filter-cell{padding:4px!important;display:flex;align-items:center;gap:8px;width:100%}.filter-cell .filter-applied{background-color:#bddef9}.border-right{border-right:1px solid #d9d9db}.merged-grid{display:grid;grid-auto-rows:40px;border-bottom:1px solid #ccc}.span-two-rows{grid-row:span 2;display:flex;justify-content:space-between;align-items:center}.group-header{display:flex;justify-content:space-between;position:relative}.group-header-content{position:sticky;left:10px;overflow:hidden;text-overflow:ellipsis}.resize-handle{width:6px;cursor:e-resize;right:0;top:0;color:#00000026}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden;box-shadow:none!important}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow;backface-visibility:hidden}.data-grid-row:hover{transform:translate(2px);box-shadow:2px 0 8px #007bff1a}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0;background:#f6f8ff}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0;border-right:1px solid #d9d9db}.right-pinned{right:0;border-left:1px solid #d9d9db}.center-scrollable{z-index:unset!important;overflow-x:auto;overflow-y:visible;white-space:nowrap;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable::-webkit-scrollbar{display:none}.data-grid-body-wrapper{display:flex}.data-grid-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-grid-body-wrapper::-webkit-scrollbar{display:none}.center-scrollable-body{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.center-scrollable-body::-webkit-scrollbar{display:none}.left-pinned-body,.right-pinned-body{position:sticky;top:0;z-index:unset;background:#f6f8ff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:-15px;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:16px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;margin-right:8px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.three-dots:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.three-dots:hover{background-color:#007bff1a;transform:rotate(90deg)}.three-dots:hover:before{width:28px;height:28px}.three-dots:active{transform:rotate(90deg) scale(.95);transition-duration:.15s}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:6px;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.filter-icon-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.filter-icon-wrapper:hover{background-color:#007bff1a;transform:scale(1.05)}.filter-icon-wrapper:hover:before{width:32px;height:32px}.filter-icon-wrapper:active{transform:scale(.95);transition-duration:.15s}.column-panel-item{font-size:.875rem;color:#333;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.column-panel-item:hover{background-color:#007bff0d;color:#007bff;transform:translate(2px)}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:4px;padding:2px}.toggle-icon:hover{background-color:#007bff1a;transform:scale(1.1)}.toggle-icon:active{transform:scale(.95)}.grab-icon{cursor:grab;color:#6c757d;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.grab-icon:hover{color:#007bff;transform:scale(1.1)}.grab-icon:active{cursor:grabbing;transform:scale(.95)}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:6px;display:flex;justify-content:center;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);margin-right:8px;transform:translateZ(0);position:relative}.chevron-wrapper:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#007bff1a;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.chevron-wrapper:hover{background-color:#007bff1a;transform:scale(1.1)}.chevron-wrapper:hover:before{width:36px;height:36px}.chevron-wrapper:hover i{transform:scale(1.2);transition:transform .25s cubic-bezier(.4,0,.2,1)}.chevron-wrapper:active{transform:scale(.95);transition-duration:.15s}.chevron-wrapper i{font-size:14px;transition:transform .25s cubic-bezier(.4,0,.2,1)}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:6px}.columns-button:hover{background-color:#007bff1a;transform:scale(1.05)}.columns-button:active{transform:scale(.95)}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff;cursor:default;animation:slideInRight .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);border-radius:8px;box-shadow:0 8px 32px #0000001f;backdrop-filter:blur(8px)}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.action-button:hover{transform:translateY(-1px);box-shadow:0 4px 12px #007cf54d}.action-button:active{transform:translateY(0);transition-duration:.15s}.global-search{max-width:380px!important}.global-search span{margin-top:2px}.global-search input{padding-left:28px;border-radius:8px!important;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.global-search input:focus{outline:none!important;box-shadow:0 0 0 3px #007bff1a!important;border-color:#007bff!important;transform:scale(1.02)}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0}.custom-menu .dropdown-item{font-size:14px;padding:8px 14px}.custom-menu .dropdown-item:hover{background-color:#f5f5f5;border-radius:6px}.table-layout{right:0}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.page-buttons button:hover:not(:disabled){background-color:#007bff1a;border-color:#007bff;transform:translateY(-1px)}.page-buttons button:active:not(:disabled){transform:translateY(0) scale(.98)}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0!important}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0!important}.text-filter input:focus,.text-filter select:focus{box-shadow:none!important}.active-filters{background-color:#f7f7f7;white-space:nowrap;background:#f7f7f7;padding-inline:8px;height:28px;font-size:14px;font-weight:500;border-radius:8px;box-shadow:none}.active-filters .header-tag{white-space:nowrap}.filter-tags .active{background-color:#e6f2ff}.filter-tags .active .header-tag{color:#007cf5!important}.table-cell{cursor:pointer;width:100%}.table-cell input:focus{outline:0!important;border:0!important;width:100%!important;box-shadow:none!important}.active-for-editing{outline:2.5px solid #007cf5!important;border-radius:4px;border:0!important;width:100%!important}.active-cell{outline:none!important;box-shadow:inset 0 0 0 1.5px #007cf5}span[inlineSVG]{width:16px;height:16px;display:inline-block}.cell .dropdown-menu{min-width:unset!important}.cell .dropdown-menu .item{transition:background-color .3s ease;display:flex;align-items:center;-webkit-user-select:none;user-select:none}.cell .dropdown-menu .item:hover{background-color:#f0f8ff}.cell .cell-editin-dropdown{scrollbar-width:thin!important;-webkit-user-select:none;user-select:none}.fw-semibold{font-weight:500!important}:host ::ng-deep .three-dots-col-menu svg,:host ::ng-deep .three-dots-col-menu svg path{stroke:#000!important}.fs-7{font-size:12px!important}.fs-8{font-size:10px!important}.all-filters-reset-button:hover{opacity:.7}.full-text-box{background:#fff;position:relative;display:flex;align-items:center;justify-content:center;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026}.full-text-content{border-radius:8px;max-width:600px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{letter-spacing:.5px}.header-cell,.cell{box-sizing:border-box}.transparent-border-right{border-right:1px solid transparent!important}.resizing-highlight{position:relative}.resizing-highlight:before{content:\"\";position:absolute;top:-1px;right:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right{position:relative}.resizing-highlight-right:before{content:\"\";position:absolute;top:-1px;left:-1px;width:2px;height:calc(100% + 2px);background:#7cb9f6;z-index:1000;pointer-events:none}.resizing-highlight-right:first-child{width:1px}.editable-header{border-bottom:1px dashed #666}.muted-text{color:#727272!important}.context-menu{position:fixed;display:none;background:#fff;border:1px solid #dcdcdc;box-shadow:#0000003d 0 3px 8px;z-index:1000;width:150px;border-radius:8px;font-weight:600}.context-menu.show{display:block}.context-menu ul{list-style:none;margin:0;padding:0}.context-menu li{padding:10px;cursor:pointer;color:#99a1b7}.context-menu li ::ng-deep svg{width:16px;height:16px;display:inline-block;color:#727272}.context-menu li ::ng-deep svg path{stroke:#727272}.context-menu li:hover{background-color:#f0f0f5!important}.invisible{visibility:hidden!important}.fw-500{font-weight:500!important}.taskbar{position:fixed;bottom:0;left:45%;display:flex;justify-content:center;z-index:1000;padding:36px}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{font-size:14px;padding:6px 12px;border-radius:6px;text-align:center;height:auto;min-height:28px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;line-height:1.5;white-space:nowrap;transition:all .2s cubic-bezier(.4,0,.2,1);will-change:transform,opacity;backface-visibility:hidden;transform:translateZ(0)}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe;animation:pulse .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0);position:relative}.selected-cell:before,.row-selected:before{content:\"\";position:absolute;inset:0;background:linear-gradient(45deg,transparent,rgba(255,255,255,.1),transparent);animation:shimmer 1.5s ease-in-out infinite}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.right-border{border-right:2px solid #2196f3!important}.top-left-corner{border-top-left-radius:4px}.top-right-corner{border-top-right-radius:4px}.bottom-left-corner{border-bottom-left-radius:4px}.bottom-right-corner{border-bottom-right-radius:4px}.flash-bg{animation:flashAnim 1000s ease}@keyframes flashAnim{0%{background-color:#48a2fc}50%{background-color:#c2e0fe}to{background-color:#c2e0fe}}.cut-flash-bg{animation:cut-flash .8s ease}@keyframes cut-flash{0%{background-color:#f006}50%{background-color:#f00c}to{background-color:#c2e0fe}}.accordion-details.dragging th,.accordion-details.dragging td{pointer-events:none}.accordion-details.dragging th{z-index:2}.drag-handle{cursor:move;opacity:.5;transition:opacity .2s}.drag-handle:hover{opacity:1}.detail-edit-input{z-index:100;position:relative}.detail-filter-menu{position:absolute;background:#fff;border:1px solid #ddd;border-radius:4px;padding:10px;z-index:1000;box-shadow:0 2px 8px #00000026}.resize-handle{cursor:col-resize;opacity:.5;width:8px;display:flex;align-items:center;justify-content:center}.resize-handle:hover{opacity:1;background-color:#f0f0f0}.detail-header-row{transition:all .3s ease}.detail-header-row.dragging{opacity:.7;transform:translate(5px)}.detail-cell{transition:background-color .2s ease,transform .3s ease}.detail-cell.active-drag{background-color:#f0f0f0;transform:scale(1.02)}.break-color-paid{background-color:#4caf50!important}.break-color-unpaid{background-color:#f44336!important}.break-color-lunch{background-color:#2196f3!important}.break-color-default{background-color:#f44336!important}.circle-value{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background-color:#f8f9fa;border:2px solid #d9d9db;font-size:12px;font-weight:600;color:#000;text-align:center;line-height:1;vertical-align:middle;box-sizing:border-box;white-space:nowrap;overflow:hidden;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.circle-value:hover{background-color:#e9ecef;box-shadow:0 6px 16px #007bff40;transform:scale(1.15) translateY(-2px);border-color:#007bff}.circle-value:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.break-tooltip-wrapper{position:relative;display:inline-block}.break-tooltip-wrapper:hover .custom-break-tooltip{opacity:1;visibility:visible}.circle-value[title]{position:relative}.circle-value[title]:after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px 8px;border-radius:4px;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .2s ease;pointer-events:none}.circle-value[title]:hover:after{opacity:1}.custom-tooltip{position:fixed;background:#fff;border:1px solid #dcdcdc;border-radius:8px;padding:12px 16px;max-width:300px;z-index:9999;font-size:13px;animation:fadeIn .2s ease-in-out}.tooltip-title{font-size:14px;font-weight:600;margin-bottom:8px;color:#333}.tooltip-list{margin:0;padding-left:16px;list-style-type:disc}.tooltip-list li{margin-bottom:4px;line-height:1.4;color:#444}.tooltip-total{font-weight:700;margin-top:8px;color:#222}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.restriction-indicator{position:absolute;display:inline-block;padding-right:10px}.restriction-indicator:after{content:\"\";position:absolute;top:0;right:0;width:8px;height:8px;background-color:#0d6efd;border-radius:50%}.manual-logs-indicator{position:absolute;top:2px;right:2px;width:8px;height:8px;background-color:#0d6efd;border-radius:50%;border:1px solid #fff;box-shadow:0 0 2px #0d6efd80;cursor:pointer;z-index:10;transition:all .2s ease}.manual-logs-indicator:hover{transform:scale(1.2);box-shadow:0 0 4px #0d6efdcc}.manual-logs-table-tooltip{background:#fff!important;border:1px solid #dcdcdc!important;border-radius:8px!important;box-shadow:0 4px 12px #00000026!important;font-size:13px!important;animation:fadeIn .2s ease-in-out!important;display:block!important;visibility:visible!important;opacity:1!important}.manual-logs-table-tooltip .popover__content,.manual-logs-table-tooltip .modal-area{padding:0!important;display:block!important;visibility:visible!important}.manual-logs-table-tooltip .table-responsive{max-height:300px;overflow-y:auto;display:block!important;visibility:visible!important}.manual-logs-table-tooltip table{margin:0!important;border-collapse:collapse!important;display:table!important;visibility:visible!important}.manual-logs-table-tooltip table th,.manual-logs-table-tooltip table td{padding:6px 8px!important;border:1px solid #f1f1f1!important;text-align:center!important;vertical-align:middle!important;display:table-cell!important;visibility:visible!important}.manual-logs-table-tooltip table th{background-color:#f8f9fa!important;font-weight:600!important;color:#495057!important;position:sticky!important;top:0!important;z-index:1!important}.manual-logs-table-tooltip table tbody tr:nth-child(2n){background-color:#f8f9fa!important}.manual-logs-table-tooltip table tbody tr:hover{background-color:#e3f2fd!important}.manual-logs-table-tooltip table .text-primary{color:#0d6efd!important;text-decoration:none!important}.manual-logs-table-tooltip table .capitalize{text-transform:capitalize!important}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%) translateY(-110%)}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.detail-column-menu{max-height:250px;overflow-y:auto;overflow-x:auto;white-space:nowrap;padding:8px 0;border-radius:6px;scrollbar-width:thin}.detail-column-menu-wrapper{z-index:1001;position:absolute}.accordion-details{position:relative;z-index:999}.detail-column-menu .column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:all .25s cubic-bezier(.4,0,.2,1);font-size:14px;transform:translateZ(0);border-radius:4px}.detail-column-menu .column-menu-item:hover{background-color:#007bff1a;transform:translate(2px);color:#007bff}.detail-column-menu .column-menu-item:active{transform:translate(0) scale(.98)}.detail-column-menu .column-menu-item:hover{background-color:#deebf7}.nested-table th[pinned=left],.nested-table td[pinned=left]{border-right:2px solid #ccc;border-left:none;border-bottom:2px solid #ccc}.nested-table th[pinned=right],.nested-table td[pinned=right]{border-left:2px solid #ccc;border-right:none;border-bottom:2px solid #ccc}.data-grid-accordion-table.show-borders{border:1px solid #d9d9db;border-collapse:collapse}.data-grid-accordion-table.show-borders th,.data-grid-accordion-table.show-borders td{border:1px solid #d9d9db}.data-grid-accordion-table.show-shadow tbody tr:hover{box-shadow:0 4px 8px #0000001a;transition:box-shadow .3s ease}.data-grid-accordion-table tbody tr:hover{background-color:#deebf7;transition:background-color .3s ease}.data-grid-pin-icon{display:inline-block;vertical-align:middle;margin-left:4px}.accordion-details.center-section{position:relative;display:flex}.detail-side-menu-wrapper{display:flex;flex-shrink:0;position:sticky;right:0;top:0;height:100%;max-height:275px}.detail-side-menu-content{width:250px;box-shadow:-2px 0 5px #0000001a;display:flex;flex-direction:column}.side-menu-scrollable{flex:1;overflow-y:auto;padding:0 12px 12px;max-height:calc(100% - 40px)}.filter-input-container{padding:8px;background:#f9f9f9;border-radius:4px}.toggle-icon.rotate{transform:rotate(90deg)}.resize-handle{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handle:hover{opacity:1;background:#007bff1a}.resize-handle:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handle{opacity:40}.resize-handles{top:0;right:3px;bottom:0;width:8px;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;position:absolute;opacity:1.4;transition:all .25s cubic-bezier(.4,0,.2,1);background:transparent;transform:translateZ(0)}.resize-handles:hover{opacity:1;background:#007bff1a}.resize-handles:active{opacity:1;background:#007bff33;transform:scaleX(1.2)}th:hover .resize-handles{opacity:40}.resizing-highlight{background-color:#007bff1a!important}.accordion-details-wrapper{display:flex;width:100%;max-height:350px;overflow:hidden}.accordion-details.show-borders,.accordion-details-wrapper.show-borders{border:1px solid #d9d9db;border-radius:4px}.accordion-left-section,.accordion-right-section,.detail-side-menu-wrapper{flex-shrink:0;max-height:350px;overflow:hidden}.accordion-center-section{flex:1;min-width:0;overflow:auto;max-height:350px}.detail-virtual-scroll{display:block;width:100%;height:250px;overflow:auto}.detail-virtual-scroll table{table-layout:fixed;width:100%}.detail-virtual-scroll td,.detail-virtual-scroll th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.detail-header-scroll-container{scrollbar-width:none}.detail-header-scroll-container::-webkit-scrollbar{display:none}.accordion-left-section thead th,.accordion-right-section thead th{position:sticky;top:0;z-index:2}.data-pin-body-wrapper{-webkit-user-select:none;user-select:none;display:flex}.data-pin-body-wrapper{scrollbar-width:none;-ms-overflow-style:none}.data-pin-body-wrapper::-webkit-scrollbar{display:none}.detail-virtual-scroll .selected-cell,.accordion-left-section .selected-cell,.accordion-right-section .selected-cell{background-color:#cce5ff!important}.custom-datepicker-buttons button{height:28px;padding:0 10px;font-size:12px}.manual-logs-modal{max-width:800px;max-height:80vh;overflow:hidden;border-radius:12px;box-shadow:0 10px 40px #0003}.manual-logs-modal .modal-header{background:linear-gradient(135deg,#4361ee,#3a0ca3);color:#fff;padding:16px 20px;border-bottom:none;border-radius:12px 12px 0 0}.manual-logs-modal .modal-header .modal-title{font-weight:600;font-size:18px;margin:0}.manual-logs-modal .modal-header .btn-close{background:#fff3;border:none;border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;color:#fff;opacity:.8;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.manual-logs-modal .modal-header .btn-close:hover{background:#ffffff4d;opacity:1;transform:scale(1.1) rotate(90deg)}.manual-logs-modal .modal-header .btn-close:active{transform:scale(.95) rotate(90deg)}.manual-logs-modal .modal-body{padding:20px;max-height:calc(80vh - 80px);overflow-y:auto}.manual-logs-modal .modal-body .table-responsive{border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a}.manual-logs-modal .modal-body .table-responsive .table{margin-bottom:0;font-size:14px}.manual-logs-modal .modal-body .table-responsive .table thead th{background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-bottom:2px solid #dee2e6;font-weight:600;color:#495057;padding:12px 16px;position:sticky;top:0;z-index:10}.manual-logs-modal .modal-body .table-responsive .table tbody tr{transition:background-color .2s ease}.manual-logs-modal .modal-body .table-responsive .table tbody tr:hover{background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr:nth-child(2n){background-color:#f8f9fa}.manual-logs-modal .modal-body .table-responsive .table tbody tr td{padding:10px 16px;vertical-align:middle;border-color:#e9ecef}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary{color:#0d6efd!important;font-weight:500;text-decoration:none}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .text-primary:hover{text-decoration:underline}.manual-logs-modal .modal-body .table-responsive .table tbody tr td .capitalize{text-transform:capitalize}::ng-deep bs-daterangepicker-container .bs-datepicker{border-radius:4px!important;box-shadow:0 2px 8px #0000001a!important;font-size:14px!important;display:flex!important;align-items:flex-start!important;left:142px!important}::ng-deep .bs-datepicker-head{background:#f8f9fa!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;padding:8px 12px!important;border-radius:4px 4px 0 0!important}::ng-deep .bs-datepicker-head .current{font-weight:600!important;color:#495057!important;font-size:13px!important}::ng-deep .bs-datepicker-head .previous,::ng-deep .bs-datepicker-head .next{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;width:24px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker-head .previous:hover,::ng-deep .bs-datepicker-head .next:hover{background:#e9ecef!important}::ng-deep .bs-datepicker .bs-datepicker-buttons{padding:8px!important;background:#f8f9fa!important;border-top:1px solid #dee2e6!important;border-radius:0 0 4px 4px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary{background:#007bff!important;color:#fff!important;border:1px solid #007bff!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-primary:hover{background:#0056b3!important;border-color:#0056b3!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary{background:#fff!important;color:#495057!important;border:1px solid #dee2e6!important;font-weight:500!important;padding:4px 8px!important;border-radius:4px!important;font-size:12px!important}::ng-deep .bs-datepicker .bs-datepicker-buttons .btn-secondary:hover{background:#e9ecef!important}::ng-deep .bs-datepicker-body{background:#fff!important;padding:6px!important}::ng-deep .bs-datepicker-body table{background:#fff!important;border-collapse:separate!important;border-spacing:1px!important}::ng-deep .bs-datepicker-body table th,::ng-deep .bs-datepicker-body table td{border:1px solid #dee2e6!important;border-radius:4px!important;text-align:center!important;font-weight:500!important;color:#495057!important;cursor:pointer!important;transition:all .2s ease!important;font-size:12px!important;width:32px!important;height:32px!important;line-height:24px!important}::ng-deep .bs-datepicker-body table th{background:#f8f9fa!important;font-weight:600!important;font-size:11px!important;padding:2px!important;height:24px!important;line-height:20px!important}::ng-deep .bs-datepicker-body table td:hover:not(.disabled){background:#e9ecef!important}::ng-deep .bs-datepicker-body table td.active{background:#007bff!important;color:#fff!important;border-color:#007bff!important}::ng-deep .bs-datepicker-body table td.is-other-month{color:#6c757d!important;background:#f8f9fa!important}::ng-deep .bs-datepicker-body table td.disabled{color:#adb5bd!important;background:#e9ecef!important;cursor:not-allowed!important}::ng-deep .bs-datepicker-custom-range{background:transparent!important;border-right:1px solid #dee2e6!important;padding:6px!important;width:130px!important;margin-right:8px!important;align-self:flex-start!important}::ng-deep .bs-datepicker-predefined-btns{display:flex!important;flex-direction:column!important;gap:2px!important}::ng-deep .bs-datepicker-predefined-btns button{background:transparent!important;color:#495057!important;border:1px solid #dee2e6!important;border-radius:4px!important;padding:4px 6px!important;font-size:11px!important;font-weight:500!important;text-align:left!important;cursor:pointer!important;transition:all .2s ease!important;width:100%!important;margin:0!important}::ng-deep .bs-datepicker-predefined-btns button:hover{background:#e9ecef!important;border-color:#adb5bd!important}::ng-deep .bs-datepicker-predefined-btns button:active,::ng-deep .bs-datepicker-predefined-btns button:focus{outline:none!important;box-shadow:0 0 0 2px #007bff40!important;background:#007bff!important;color:#fff!important;border-color:#007bff!important}.manual-logs-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:9999}.manual-logs-modal-content{background:#fff;border-radius:8px;max-width:800px;max-height:80vh;overflow:auto;box-shadow:0 4px 8px #0000001a}.popover__wrapper{position:relative;display:inline-block}.popover__content{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;box-shadow:0 4px 12px #00000026;z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease;min-width:250px;max-width:400px;font-size:14px}.popover__wrapper:hover .popover__content{opacity:1;visibility:visible}.popover__content .modal-area{padding:0}.popover__content h4{margin:0 0 8px;font-size:16px;font-weight:600;color:#333}.popover__content .break-status{font-size:12px;color:#666;margin-bottom:8px}.popover__content .d-flex{gap:12px}.popover__content p{margin:0 0 4px;font-size:12px;color:#666}.popover__content h5{margin:0;font-size:14px;font-weight:500;color:#333}.popover__content .break-footer{border-top:1px solid #eee;margin-top:8px;padding-top:8px}.popover__content .break-footer p{font-size:12px;color:#666;margin:0}.custom-break-tooltip{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;font-size:13px;max-width:220px;pointer-events:none;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips{position:fixed;z-index:1000;background:#fff;border:1px solid #ddd;border-radius:8px;box-shadow:0 4px 12px #00000026;padding:8px;font-size:12px;max-width:500px;max-height:300px;top:0;left:0;transform:translate(var(--tooltip-x, 0px),var(--tooltip-y, 0px))}.custom-break-tooltips .modal-body{max-height:250px!important;overflow-y:auto;padding:0}.custom-break-tooltips .table-responsive{max-height:250px}.custom-break-tooltips thead th{position:sticky;top:0;background:#f8f9fa;z-index:10;border-bottom:2px solid #dee2e6;font-size:11px;padding:4px 8px;font-weight:600}.custom-break-tooltips table{font-size:11px;margin-bottom:0}.custom-break-tooltips table td{padding:4px 8px;white-space:nowrap}.custom-break-tooltips .table-striped tbody tr:nth-of-type(odd){background-color:#00000005}.popver_content_progress_bar{visibility:hidden}.badge-overflow-container{display:flex;flex-wrap:nowrap;gap:4px;align-items:center;min-width:0;overflow:hidden;width:100%}.badge-overflow-container .badge{flex-shrink:0;white-space:nowrap;font-size:12px;padding:4px 8px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:600;line-height:1;text-transform:uppercase;letter-spacing:.5px;transition:all .3s cubic-bezier(.4,0,.2,1);border:2px solid transparent;width:32px;height:32px;box-sizing:border-box;cursor:pointer;transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge:hover{transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.badge-overflow-container .badge-overflow-count{background-color:#6c757d!important;color:#fff!important;cursor:pointer;border:2px solid #6c757d!important;flex-shrink:0;border-radius:50%;width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;font-weight:600;transition:all .3s cubic-bezier(.4,0,.2,1);transform:translateZ(0);will-change:transform,box-shadow,background-color;backface-visibility:hidden}.badge-overflow-container .badge-overflow-count:hover{background-color:#5a6268!important;border-color:#5a6268!important;transform:scale(1.15) translateY(-2px);box-shadow:0 6px 16px #007bff40}.badge-overflow-container .badge-overflow-count:active{transform:scale(1.08) translateY(-1px);transition-duration:.15s}.timeline-view-container{padding:1rem;background-color:#f8f9fa}.timeline-view-container .timeline-header{margin-bottom:2rem}.timeline-view-container .timeline-header h5{color:#495057;font-weight:600;margin-bottom:1rem}.timeline-view-container .timeline-header .timeline-hours{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px solid #dee2e6;margin-bottom:1rem;background:#fff;border-radius:8px;padding:1rem}.timeline-view-container .timeline-header .timeline-hours .timeline-hour{font-size:.8rem;color:#6c757d;font-weight:500;min-width:40px;text-align:center;padding:.5rem;border-radius:4px;background:#f8f9fa}.timeline-view-container .timeline-body .timeline-row{background:#fff;border:1px solid #dee2e6;border-radius:8px;margin-bottom:1rem;padding:1rem;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.timeline-view-container .timeline-body .timeline-row:hover{box-shadow:0 4px 8px #00000026}.timeline-view-container .timeline-body .timeline-row .timeline-employee{margin-bottom:1rem}.timeline-view-container .timeline-body .timeline-row .timeline-employee .employee-name{font-weight:600;color:#495057;font-size:1.1rem}.timeline-view-container .timeline-body .timeline-row .timeline-track{position:relative;height:40px;background:#f8f9fa;border-radius:4px;border:1px solid #e9ecef}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar{position:absolute;height:100%;background:linear-gradient(135deg,#28a745,#20c997);border-radius:4px;box-shadow:0 2px 4px #28a7454d;transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .work-duration-bar:hover{opacity:.8}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar{position:absolute;height:100%;border-radius:4px;box-shadow:0 2px 4px #0003;border:1px solid rgba(255,255,255,.5);transition:opacity .2s ease}.timeline-view-container .timeline-body .timeline-row .timeline-track .break-bar:hover{opacity:.8}.calendar-view-container .calendar-header{margin-bottom:2rem}.calendar-view-container .calendar-header h5{color:#495057;font-weight:600}.calendar-view-container .calendar-header .calendar-nav button{border:1px solid #dee2e6;background:#fff;color:#495057;padding:.375rem .75rem;border-radius:.375rem;transition:all .2s ease}.calendar-view-container .calendar-header .calendar-nav button:hover{background-color:#f8f9fa;border-color:#adb5bd}.calendar-view-container .calendar-header .calendar-nav button:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.calendar-view-container .calendar-header .calendar-nav button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.calendar-view-container .calendar-grid .calendar-week-header{display:flex;background-color:#f8f9fa;border:1px solid #dee2e6;border-bottom:none}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header{flex:1;padding:.75rem;text-align:center;font-weight:600;color:#495057;border-right:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-week-header .calendar-day-header:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks{border:1px solid #dee2e6;border-top:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week{display:flex;border-bottom:1px solid #dee2e6}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week:last-child{border-bottom:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day{flex:1;min-height:100px;padding:.5rem;border-right:1px solid #dee2e6;background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day:last-child{border-right:none}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.current-month{background:#fff}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day.today{background-color:#fff3cd;border:2px solid #ffc107}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-number{font-weight:600;color:#495057;margin-bottom:.25rem}.calendar-view-container .calendar-grid .calendar-weeks .calendar-week .calendar-day .day-entries .entry-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:2px;margin-bottom:2px}.heatmap-view-container .heatmap-header{margin-bottom:2rem}.heatmap-view-container .heatmap-header h5{color:#495057;font-weight:600}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors{display:flex;margin:0 1rem}.heatmap-view-container .heatmap-header .heatmap-legend .legend-colors .legend-color{width:12px;height:12px;margin-right:2px;border-radius:2px}.heatmap-view-container .heatmap-header .heatmap-legend span{font-size:.875rem;color:#6c757d}.heatmap-view-container .heatmap-grid .heatmap-months{display:flex;margin-bottom:.5rem}.heatmap-view-container .heatmap-grid .heatmap-months .month-label{flex:1;text-align:center;font-size:.8rem;font-weight:600;color:#495057}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week{display:flex;margin-bottom:2px}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day{flex:1;aspect-ratio:1;border-radius:2px;margin-right:2px;transition:opacity .2s ease}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:hover{opacity:.8}.heatmap-view-container .heatmap-grid .heatmap-weeks .heatmap-week .heatmap-day:last-child{margin-right:0}.card-view-container{padding:1rem;height:100%;overflow-y:auto;overflow-x:hidden}.card-view-container[data-theme=white]{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card{background-color:#f6f8ff;border-color:#d9d9db;color:#000}.card-view-container[data-theme=white] .attendance-card:hover{background-color:#007bff1a}.card-view-container[data-theme=white] .attendance-card .card-header{background-color:#f8f9fa;color:#000;border-bottom-color:#d9d9db}.card-view-container[data-theme=white] .attendance-card .card-body{background-color:#f6f8ff;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-success{background-color:#84ca81;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-danger{background-color:#ea5353;color:#f6f8ff}.card-view-container[data-theme=white] .attendance-card .badge.bg-warning{background-color:#fff3dc;color:#000}.card-view-container[data-theme=white] .attendance-card .badge.bg-info{background-color:#e8fbfd;color:#00bad1}.card-view-container[data-theme=blue]{background-color:#f0f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card{background-color:#f6f8ff;border-color:#b3d9ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card:hover{background-color:#1e3a5f1a}.card-view-container[data-theme=blue] .attendance-card .card-header{background-color:#e6f3ff;color:#1e3a5f;border-bottom-color:#b3d9ff}.card-view-container[data-theme=blue] .attendance-card .card-body{background-color:#f6f8ff;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-success{background-color:#69db7c;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-danger{background-color:#ff8787;color:#f6f8ff}.card-view-container[data-theme=blue] .attendance-card .badge.bg-warning{background-color:#ffd43b;color:#1e3a5f}.card-view-container[data-theme=blue] .attendance-card .badge.bg-info{background-color:#74c0fc;color:#f6f8ff}.card-view-container .row{margin:0}.card-view-container .row .col-xl-4,.card-view-container .row .col-lg-6,.card-view-container .row .col-md-6,.card-view-container .row .col-sm-12{padding:.5rem}.card-view-container .attendance-card{transition:background-color .2s ease;border:1px solid #d9d9db;border-radius:4px;overflow:hidden;height:100%;display:flex;flex-direction:column;font-family:sans-serif;font-size:16px}.card-view-container .attendance-card:hover{box-shadow:0 2px 4px #0000001a}.card-view-container .attendance-card.expanded .card-body{max-height:none}.card-view-container .attendance-card .card-header{padding:8px;border-bottom:1px solid #d9d9db;flex-shrink:0;font-weight:500}.card-view-container .attendance-card .card-header .employee-avatar{margin-right:.75rem;flex-shrink:0}.card-view-container .attendance-card .card-header .employee-avatar img,.card-view-container .attendance-card .card-header .employee-avatar .avatar-placeholder{border:1px solid #d9d9db;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400}.card-view-container .attendance-card .card-header .flex-grow-1{min-width:0}.card-view-container .attendance-card .card-header h6{margin:0;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header small{opacity:.9;font-weight:400;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-view-container .attendance-card .card-header .card-actions{flex-shrink:0}.card-view-container .attendance-card .card-header .card-actions .btn{background-color:transparent;border:1px solid #d9d9db;color:inherit;padding:.25rem .5rem}.card-view-container .attendance-card .card-header .card-actions .btn:hover{background-color:#007bff1a}.card-view-container .attendance-card .card-header .card-actions .btn i{font-size:.8rem}.card-view-container .attendance-card .card-body{padding:8px;flex:1;display:flex;flex-direction:column}.card-view-container .attendance-card .card-body .info-item{text-align:center;margin-bottom:.5rem}.card-view-container .attendance-card .card-body .info-item small{display:block;font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .info-item span{font-size:16px;font-weight:400;color:inherit}.card-view-container .attendance-card .card-body .badge{font-size:12px;padding:.25rem .5rem;border-radius:4px;font-weight:400;text-transform:uppercase;letter-spacing:.5px;border:none}.card-view-container .attendance-card .card-body .badge.bg-success,.card-view-container .attendance-card .card-body .badge.bg-danger{color:#f6f8ff}.card-view-container .attendance-card .card-body .badge.bg-warning{color:#000}.card-view-container .attendance-card .card-body .badge.bg-secondary{color:#f6f8ff}.card-view-container .attendance-card .card-body .card-details{margin-top:1rem}.card-view-container .attendance-card .card-body .card-details .section-title{font-size:14px;font-weight:500;color:inherit;margin-bottom:.75rem;display:flex;align-items:center}.card-view-container .attendance-card .card-body .card-details .section-title i{margin-right:.5rem;opacity:.8}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item{background-color:inherit;border:1px solid #d9d9db;border-radius:4px;padding:8px;margin-bottom:.5rem;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex{gap:.75rem;align-items:center}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex small,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex small{font-weight:500;color:inherit;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .text-muted,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .text-muted{font-size:12px;color:#6c757d}.card-view-container .attendance-card .card-body .card-details .breaks-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .breaks-list .leave-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .break-item .d-flex .badge,.card-view-container .attendance-card .card-body .card-details .short-leave-list .leave-item .d-flex .badge{font-size:10px;padding:.2rem .4rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6{margin-bottom:.5rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 small{font-weight:400;color:#6c757d;text-transform:uppercase;font-size:12px;letter-spacing:.5px;margin-bottom:.25rem}.card-view-container .attendance-card .card-body .card-details .additional-details .row .col-6 span{font-weight:400;color:inherit;font-size:14px}@media (max-width: 1200px){.card-view-container .row .col-xl-4{flex:0 0 50%;max-width:50%}}@media (max-width: 768px){.card-view-container .row .col-xl-4,.card-view-container .col-lg-6,.card-view-container .col-md-6{flex:0 0 100%;max-width:100%}.card-view-container .attendance-card .card-body{padding:8px}.card-view-container .attendance-card .card-body .info-item small{font-size:10px}.card-view-container .attendance-card .card-body .info-item span{font-size:14px}}@media (max-width: 576px){.card-view-container{padding:.5rem}.card-view-container .row .col-sm-12{padding:.25rem}.card-view-container .attendance-card .card-header{padding:8px}.card-view-container .attendance-card .card-header h6,.card-view-container .attendance-card .card-header small{font-size:14px}.card-view-container .attendance-card .card-body{padding:8px}}.btn-xs{padding:.125rem .3rem!important;font-size:.9rem!important;border-radius:.2rem!important;line-height:1.5!important}.form-select.form-select-sm:invalid{border-color:#d9d9db!important}.form-select.form-select-sm:valid{border-color:#d9d9db!important}.date-range-container{gap:8px;flex-wrap:nowrap;align-items:center}.date-range-btn{padding:6px 12px;font-size:14px;font-weight:500;border-radius:6px;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;min-height:36px;transform:translateZ(0);position:relative;overflow:hidden}.date-range-btn:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:#fff3;border-radius:50%;transform:translate(-50%,-50%);transition:width .25s,height .25s}.date-range-btn:active:before{width:300px;height:300px}.calendar-btn{border-color:#0d6efd;color:#0d6efd;background-color:transparent}.calendar-btn:hover{background-color:#0d6efd;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #0d6efd4d}.clear-btn{border-color:#dc3545;color:#dc3545;background-color:transparent}.clear-btn:hover{background-color:#dc3545;color:#fff;transform:translateY(-1px);box-shadow:0 4px 12px #dc35454d}.date-range-label{font-size:14px;font-weight:500;padding:4px 8px;min-width:180px;text-align:center;white-space:nowrap;cursor:pointer}.date-range-btn .bi{font-size:14px;transition:transform .2s ease}.date-range-btn:hover .bi{transform:scale(1.1)}@media (max-width: 768px){.date-range-container{flex-wrap:wrap;justify-content:flex-start}.date-range-label{min-width:100%;margin-top:8px;order:3}}.date-range-btn:focus{outline:none;box-shadow:0 0 0 3px #0d6efd40}.clear-btn:focus{box-shadow:0 0 0 3px #dc354540}.action-buttons-row .button{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:#fff;border-radius:6px;height:34px;padding:0 10px;white-space:nowrap;transition:max-width .4s ease,background-color .3s ease;max-width:40px;background-color:transparent;border:1px solid #6F61CF}.action-buttons-row .button .label-hidden{opacity:0;margin-left:8px;transition:opacity .3s ease;pointer-events:none;display:none}.action-buttons-row .button:hover{max-width:200px;background-color:#6f61cf}.action-buttons-row .button:hover .label-hidden{opacity:1;pointer-events:auto;margin-left:8px!important;display:block}.action-buttons-row ::ng-deep .button .svg-icon svg path{stroke:#6f61cf;transition:fill .3s ease,stroke .3s ease}.action-buttons-row ::ng-deep .button:hover .svg-icon svg path{stroke:#fff!important}.badge-overflow-wrapper{width:100%;min-width:0;display:flex;align-items:center}\n"] }]
8052
8126
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ViewContainerRef }, { type: CommonService }], propDecorators: { onShortBreakClick: [{
8053
8127
  type: Output
8054
8128
  }], searchEvent: [{
@@ -8201,14 +8275,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8201
8275
  type: Input
8202
8276
  }], progressiveDelay: [{
8203
8277
  type: Input
8204
- }], enableInfiniteScroll: [{
8205
- type: Input
8206
- }], hasMoreData: [{
8207
- type: Input
8208
- }], loadingMore: [{
8209
- type: Input
8210
- }], loadMoreData: [{
8211
- type: Output
8212
8278
  }], changeLayout: [{
8213
8279
  type: Output
8214
8280
  }], filterOptions: [{
@@ -8337,5 +8403,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
8337
8403
  * Generated bundle index. Do not edit.
8338
8404
  */
8339
8405
 
8340
- export { CommonService, MsTimeSheetService, TimeSheetComponent };
8406
+ export { CommonService, MsTimeSheetService, TimeSheetComponent, TimezoneFormatPipe };
8341
8407
  //# sourceMappingURL=ms-time-sheet.mjs.map