ms-data-grid 0.0.65 → 0.0.68

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.
@@ -1025,6 +1025,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1025
1025
  type: Output
1026
1026
  }] } });
1027
1027
 
1028
+ class CellEditorDirective {
1029
+ constructor(vcr, injector) {
1030
+ this.vcr = vcr;
1031
+ this.injector = injector;
1032
+ // Parent component listens using:
1033
+ // (editorEvent)="finishEdit($event)"
1034
+ this.editorEvent = new EventEmitter();
1035
+ }
1036
+ ngOnInit() {
1037
+ if (!this.componentType)
1038
+ return;
1039
+ // ✅ Dynamically create the editor component
1040
+ const componentRef = this.vcr.createComponent(this.componentType, {
1041
+ injector: Injector.create({
1042
+ providers: [
1043
+ { provide: 'rowData', useValue: this.rowData },
1044
+ { provide: 'colData', useValue: this.colData },
1045
+ { provide: 'cellValue', useValue: this.cellValue }
1046
+ ],
1047
+ parent: this.injector
1048
+ })
1049
+ });
1050
+ // -----------------------------------------------
1051
+ // 1️⃣ Call custom lifecycle hook if it exists
1052
+ // -----------------------------------------------
1053
+ if (typeof componentRef.instance.editorInit === 'function') {
1054
+ componentRef.instance.editorInit({
1055
+ row: this.rowData,
1056
+ col: this.colData,
1057
+ value: this.cellValue
1058
+ });
1059
+ }
1060
+ // -----------------------------------------------
1061
+ // 2️⃣ Auto-detect all @Output() EventEmitters
1062
+ // -----------------------------------------------
1063
+ for (const key of Object.keys(componentRef.instance)) {
1064
+ const property = componentRef.instance[key];
1065
+ // Check if any property is an EventEmitter
1066
+ if (property instanceof EventEmitter) {
1067
+ property.subscribe((value) => {
1068
+ this.editorEvent.emit({
1069
+ eventName: key,
1070
+ data: {
1071
+ row: this.rowData,
1072
+ col: this.colData,
1073
+ value
1074
+ }
1075
+ });
1076
+ });
1077
+ }
1078
+ }
1079
+ }
1080
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellEditorDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive }); }
1081
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CellEditorDirective, selector: "[cellEditor]", inputs: { componentType: ["cellEditor", "componentType"], rowData: "rowData", colData: "colData", cellValue: "cellValue" }, outputs: { editorEvent: "editorEvent" }, ngImport: i0 }); }
1082
+ }
1083
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellEditorDirective, decorators: [{
1084
+ type: Directive,
1085
+ args: [{
1086
+ selector: '[cellEditor]'
1087
+ }]
1088
+ }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Injector }]; }, propDecorators: { componentType: [{
1089
+ type: Input,
1090
+ args: ['cellEditor']
1091
+ }], rowData: [{
1092
+ type: Input
1093
+ }], colData: [{
1094
+ type: Input
1095
+ }], cellValue: [{
1096
+ type: Input
1097
+ }], editorEvent: [{
1098
+ type: Output
1099
+ }] } });
1100
+
1028
1101
  class FilterPipe {
1029
1102
  transform(items, searchText, key) {
1030
1103
  if (!items || !searchText)
@@ -2051,6 +2124,8 @@ class DataGridComponent {
2051
2124
  this.selectedTableLayout = temprorySelected.config.selectedTableLayout;
2052
2125
  this.bodyTextFontsSize = temprorySelected.config.bodyTextFontsSize;
2053
2126
  this.globalSearchText = temprorySelected.config.globalSearch;
2127
+ this.setTableLayout(this.selectedTableLayout);
2128
+ this.oddRowsBackgroundColor = temprorySelected?.config?.oddRowsBackgroundColor || '#f1f1f1';
2054
2129
  this.cdr.detectChanges();
2055
2130
  }
2056
2131
  else {
@@ -2058,17 +2133,22 @@ class DataGridComponent {
2058
2133
  this.showVerticalBorder = false;
2059
2134
  this.fontFaimly = 'Inter';
2060
2135
  this.headerTextFontsSize = 14;
2061
- this.selectedTableLayout = 'mediumd';
2136
+ this.selectedTableLayout = 'medium';
2062
2137
  this.bodyTextFontsSize = 14;
2063
2138
  this.globalSearchText = '';
2064
2139
  // this.autosizeAllColumns();
2065
2140
  }
2066
- }, 100);
2141
+ this.cdr.detectChanges();
2142
+ }, 500);
2067
2143
  }
2068
2144
  }
2069
2145
  async setColumnsColumnDropdownValus() {
2070
2146
  if (!this.columns)
2071
2147
  return;
2148
+ // Just removed temporary for super admin will set it again
2149
+ if (this.columns?.length) {
2150
+ this.columns = this.columns?.filter(c => c?.field?.trim() !== 'is_deleted');
2151
+ }
2072
2152
  this.columns = await this.commonSevice.copyDropdownDataRecursively(this.columns);
2073
2153
  }
2074
2154
  applyRowsSelectionState() {
@@ -3595,24 +3675,7 @@ class DataGridComponent {
3595
3675
  let target = event.target;
3596
3676
  if (target.checked) {
3597
3677
  this.selectedTableLayout = layoutType;
3598
- if (layoutType === 'small') {
3599
- this.rowHeight = 36;
3600
- this.headerRowHeight = 40;
3601
- this.bodyTextFontsSize = 10;
3602
- this.headerTextFontsSize = 10;
3603
- }
3604
- else if (layoutType === 'medium') {
3605
- this.rowHeight = 44;
3606
- this.headerRowHeight = 44;
3607
- this.bodyTextFontsSize = 14;
3608
- this.headerTextFontsSize = 14;
3609
- }
3610
- else {
3611
- this.rowHeight = 60;
3612
- this.headerRowHeight = 52;
3613
- this.bodyTextFontsSize = 16;
3614
- this.headerTextFontsSize = 16;
3615
- }
3678
+ this.setTableLayout(layoutType);
3616
3679
  this.updateVisibleRows(this.mainScroll?.nativeElement?.scrollTop);
3617
3680
  await this.refreshHeaders();
3618
3681
  }
@@ -3621,6 +3684,28 @@ class DataGridComponent {
3621
3684
  }
3622
3685
  this.onFontChange();
3623
3686
  }
3687
+ setTableLayout(layoutType) {
3688
+ if (!layoutType)
3689
+ return;
3690
+ if (layoutType === 'small') {
3691
+ this.rowHeight = 36;
3692
+ this.headerRowHeight = 40;
3693
+ this.bodyTextFontsSize = 10;
3694
+ this.headerTextFontsSize = 10;
3695
+ }
3696
+ else if (layoutType === 'medium') {
3697
+ this.rowHeight = 44;
3698
+ this.headerRowHeight = 44;
3699
+ this.bodyTextFontsSize = 14;
3700
+ this.headerTextFontsSize = 14;
3701
+ }
3702
+ else {
3703
+ this.rowHeight = 60;
3704
+ this.headerRowHeight = 52;
3705
+ this.bodyTextFontsSize = 16;
3706
+ this.headerTextFontsSize = 16;
3707
+ }
3708
+ }
3624
3709
  get startIndexData() {
3625
3710
  return (this.paginationConfig.page - 1) * this.paginationConfig.limit;
3626
3711
  }
@@ -3700,6 +3785,7 @@ class DataGridComponent {
3700
3785
  this.activeFilterCell = col;
3701
3786
  this.activeCol = null;
3702
3787
  this.isFilterOpen = true;
3788
+ this.searchTextForFilterDropDown = '';
3703
3789
  this.addFilterColumnInput = '';
3704
3790
  this.selectedColumnForFilter = col;
3705
3791
  if (col.type === 'dropdown') {
@@ -3787,8 +3873,8 @@ class DataGridComponent {
3787
3873
  column.query = {
3788
3874
  first_condition: this.firstCondition || 'contain',
3789
3875
  first_value: this.firstValue || null,
3790
- condition: this.condition || 'none',
3791
- second_condition: this.secondCondition || null,
3876
+ condition: this.secondValue ? this.condition : 'none',
3877
+ second_condition: this.secondValue ? this.secondCondition : null,
3792
3878
  second_value: this.secondValue || null,
3793
3879
  };
3794
3880
  }
@@ -4347,7 +4433,26 @@ class DataGridComponent {
4347
4433
  },
4348
4434
  eventType: this.tableFilterViewId || !this.isTablePresetNotChanged ? 'updatePreset' : 'createPreset'
4349
4435
  };
4350
- this.genericEvent.emit(event);
4436
+ const filteredColumns = this.commonSevice.getFiltersFromColumns(this.columns, this.filtersConfig);
4437
+ const cleanedFilteredColumns = filteredColumns.map(({ query, ...rest }) => {
4438
+ if (query) {
4439
+ delete query.__typename;
4440
+ }
4441
+ return {
4442
+ query,
4443
+ ...rest,
4444
+ };
4445
+ });
4446
+ const sendData = {
4447
+ columns: this.cleanColumns(this.columns),
4448
+ filters: cleanedFilteredColumns,
4449
+ no_of_records: Number(this.paginationConfig.limit),
4450
+ type: this.tableType,
4451
+ };
4452
+ this.createUpdateConfigListing.emit(sendData);
4453
+ setTimeout(() => {
4454
+ this.genericEvent.emit(event);
4455
+ }, 500);
4351
4456
  }
4352
4457
  getFilterHeaders(filters, columns) {
4353
4458
  const matchedHeaders = filters
@@ -5371,6 +5476,8 @@ class DataGridComponent {
5371
5476
  const value = row[column.field] || 0;
5372
5477
  return sum + value;
5373
5478
  }, 0);
5479
+ if (!total)
5480
+ return `${this.currencySymbol} 0.00`;
5374
5481
  return `${this.currencySymbol} ${this.formatCurrency.transform(total, this.currencyFormat)}`;
5375
5482
  }
5376
5483
  dropColumn(event, row) {
@@ -5528,7 +5635,7 @@ class DataGridComponent {
5528
5635
  : (this.paginationConfig.page - 1) * this.paginationConfig.limit + 1 || 0;
5529
5636
  }
5530
5637
  hasAnyDefaultView() {
5531
- return this.tableView?.some((x) => x.is_default);
5638
+ return this.tableView?.some((x) => x.is_default || x.is_temp);
5532
5639
  }
5533
5640
  get isTablePresetNotChanged() {
5534
5641
  if (this.tableFilterViewId)
@@ -5578,7 +5685,14 @@ class DataGridComponent {
5578
5685
  // console.log('Current columns: ', columns);
5579
5686
  if (!currentPresetColumns)
5580
5687
  return true;
5581
- return (currentPresetColumns && (stringsCurrentPrestCols == stringColumns) && (JSON.stringify(filters) == JSON.stringify(currentPresetFilters)) && (this.fontFaimly == currPreset.config.fontFaimly) && (this.bodyTextFontsSize == currPreset.config.bodyTextFontsSize) && (this.headerTextFontsSize == this.headerTextFontsSize));
5688
+ return (currentPresetColumns && (stringsCurrentPrestCols == stringColumns) && (JSON.stringify(filters) == JSON.stringify(currentPresetFilters)) && (this.fontFaimly == currPreset.config.fontFaimly)
5689
+ && (this.bodyTextFontsSize == currPreset.config.bodyTextFontsSize) &&
5690
+ (this.headerTextFontsSize == this.headerTextFontsSize)
5691
+ && this.curretaTablePresetForUpdate.config.showVerticalBorder == this.showVerticalBorder
5692
+ && this.curretaTablePresetForUpdate.config.fontFaimly == this.fontFaimly
5693
+ && this.curretaTablePresetForUpdate.config.selectedTableLayout == this.selectedTableLayout
5694
+ && this.curretaTablePresetForUpdate.config.bodyTextFontsSize == this.bodyTextFontsSize
5695
+ && this.curretaTablePresetForUpdate.config.rowShadingEnabled == this.rowShadingEnabled);
5582
5696
  // return false
5583
5697
  }
5584
5698
  onActionButtonClick(button) {
@@ -5835,7 +5949,8 @@ class DataGridComponent {
5835
5949
  return this.commonSevice.formatDateValue(val, this.dateFormat);
5836
5950
  }
5837
5951
  else if (col?.is_amount) {
5838
- console.log('Amount colum', col);
5952
+ if (!val)
5953
+ return `0.00`;
5839
5954
  return this.formatCurrency.transform(val, this.currencyFormat);
5840
5955
  }
5841
5956
  return (val?.value ??
@@ -5849,8 +5964,11 @@ class DataGridComponent {
5849
5964
  first?.full_name ??
5850
5965
  '-');
5851
5966
  }
5967
+ finishEdit(event) {
5968
+ console.log('cell editeddddddddddddddd: ', event);
5969
+ }
5852
5970
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridComponent, deps: [{ token: SplitColumnsService }, { token: i0.ChangeDetectorRef }, { token: CommonService }, { token: i0.ElementRef }, { token: i0.NgZone }, { token: CopyServiceService }, { token: i0.Renderer2 }, { token: i4.DomSanitizer }, { token: ExportService }, { token: i6.DatePipe }, { token: FormatCurrencyPipe }], target: i0.ɵɵFactoryTarget.Component }); }
5853
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DataGridComponent, selector: "data-grid", inputs: { rowAnimation: "rowAnimation", paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", checkboxesColor: "checkboxesColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowBackgroundColor: "footerRowBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", currencySymbol: "currencySymbol", currencyFormat: "currencyFormat", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBackgroundColor: "nestedTableHeaderBackgroundColor", nestedTableRowBackgroundColor: "nestedTableRowBackgroundColor", tableView: "tableView", buttons: "buttons", keepMultipleExpandedDetails: "keepMultipleExpandedDetails", showTotalAmountRow: "showTotalAmountRow", enableGlobalSearch: "enableGlobalSearch", tableType: "tableType", enableExport: "enableExport", showFullScreenButton: "showFullScreenButton", enableCut: "enableCut", tabs: "tabs", showCheckboxes: "showCheckboxes", resetAllFilters: "resetAllFilters", columnThreedotsMunuConfig: "columnThreedotsMunuConfig" }, outputs: { changeLayout: "changeLayout", customCellEvent: "customCellEvent", filterOptions: "filterOptions", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing" }, 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: "nestedHeader", first: true, predicate: ["nestedHeader"], descendants: true }, { propertyName: "dataGridContainer", first: true, predicate: ["dataGridContainer"], descendants: true }, { propertyName: "taskManagementContainer", first: true, predicate: ["taskManagementContainer"], descendants: true }, { propertyName: "nestedTableContainer", first: true, predicate: ["nestedTableContainer"], 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: "textAreadInput", first: true, predicate: ["textAreadInput"], descendants: true }, { propertyName: "nestedTable", first: true, predicate: ["nestedTable"], descendants: true }, { propertyName: "fullscreenImageTemplate", first: true, predicate: ["fullscreenImageTemplate"], descendants: true }, { propertyName: "cellHosts", predicate: CellHostDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <div\r\n class=\"d-flex justify-content-between mb-2 align-items-center position-relative\"\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\r\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\r\n <span\r\n *ngFor=\"let tab of tabs; let i = index\"\r\n (click)=\"setActiveTab(tab)\"\r\n class=\"nav-link cursor-pointer\"\r\n [class.active]=\"activeTab == tab\"\r\n >\r\n {{ tab }}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"global-search\" [style.width.px]=\"350\">\r\n <span\r\n *ngIf=\"enableGlobalSearch\"\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 *ngIf=\"enableGlobalSearch\"\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Type to search, then press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n (input)=\"onSearchInput($event)\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n <ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\r\n *ngIf=\"button?.has_permission\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button button-small btn border border-primary btn-active-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\r\n \"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span\r\n class=\"label-hidden text-white\"\r\n [class.ms-0]=\"button.is_showIcon\"\r\n >{{ button?.name }}</span\r\n >\r\n </a>\r\n </div>\r\n </ng-container>\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\r\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\r\n <a\r\n *ngIf=\"!isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Minimise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n <a\r\n *ngIf=\"isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Maximise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\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>\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 [style.backgroundColor]=\"bodyBackgroundColor\"\r\n id=\"data-grid-main-container\"\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\r\n class=\"d-flex gap-2 align-items-center\"\r\n [style.color]=\"headerTextColor\"\r\n >\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 <div\r\n cdkDropListOrientation=\"horizontal\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onGroupReorder($event)\"\r\n class=\"d-flex\"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragLockAxis]=\"'x'\"\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n class=\"d-flex align-items-center\"\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-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\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>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\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\r\n class=\"data-grid-header left-pinned\"\r\n #leftPinnedHeader\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n >\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]=\"55\"\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\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\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 style=\"width: 16px; height: 16px\"\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 [style.backgroundColor]=\"headerBackgroundColor\"\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: 1px\"\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 *ngIf=\"!draggingInGroupArea\"\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)=\"onCenterBodyScroll($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)=\"\r\n openThreeDotsMenu($event, 'group');\r\n isThreeDotsFilterOpen = false\r\n \"\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)=\"\r\n $event.stopPropagation(); onResizeGroupBox($event)\r\n \"\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 === 'Assets' || gridType === 'Tasks'\"\r\n >\r\n </span>\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col);\r\n dragStartOnGroup(col);\r\n onDragStarted(col)\r\n \"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\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 *ngIf=\"!isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (draggingInGroupArea\r\n ? 'data-grid/icons/justify.svg'\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 >\r\n </span>\r\n <span\r\n *ngIf=\"isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\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 && !isOutsideContainer\"\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>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\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: 'right'\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 *ngIf=\"!draggingInGroupArea\"\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: 'right'\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 && !dataSetLoading\"\r\n >\r\n <!-- <div\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></div> -->\r\n <div>No Record Found</div>\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 || dataSetLoading\"\r\n style=\"\r\n z-index: 999;\r\n backdrop-filter: blur(1px);\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div class=\"spinner-border text-primary\" role=\"status\">\r\n <!-- <span class=\"loader\"></span> -->\r\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\r\n <!-- </div> -->\r\n </div>\r\n </div>\r\n\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 [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div\r\n [style.height.px]=\"\r\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\r\n \"\r\n ></div>\r\n <div [class.h-100]=\"originalDataSet.length < 8\">\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]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n\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 isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewLeftPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'left',\r\n isTotalRow: true\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=\"h-100\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container *ngIf=\"!loading && !dataSetLoading\">\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 isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewCenterColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'center',\r\n isTotalRow: true\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 < 8\"\r\n [style.maxWidth.px]=\"\r\n isScrollbarVisible\r\n ? rightPinnedHeader.offsetWidth - 15\r\n : rightPinnedHeader.offsetWidth\r\n \"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100 h-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewRightPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'right',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n style=\"top: auto; left: auto\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n fullscreenImage = null;\r\n cdr.detectChanges()\r\n \"\r\n [style.width.px]=\"dataGridContainer.offsetWidth\"\r\n [style.height.px]=\"\r\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\r\n \"\r\n class=\"image-modal full-image-modal\"\r\n *ngIf=\"fullscreenImage\"\r\n >\r\n <img\r\n (click)=\"$event.stopPropagation()\"\r\n [src]=\"fullscreenImage\"\r\n alt=\"Fullscreen Image\"\r\n />\r\n </div>\r\n <div\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar w-100\"\r\n [style.bottom.px]=\"85\"\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 {{\r\n paginationConfig.totalResults ||\r\n config?.paginationParams?.totalItems\r\n }}\r\n Total\r\n </span>\r\n <div class=\"action-buttons d-flex align-items-center\">\r\n <ng-container\r\n *ngFor=\"let action of taskbarActions; let i = index\"\r\n >\r\n <ng-container *ngIf=\"action?.has_permission\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action?.actionName)\"\r\n >{{ action?.actionName }}</span\r\n >\r\n <span\r\n *ngIf=\"\r\n taskbarActions.length > 1 &&\r\n i !== taskbarActions.length - 1 &&\r\n taskbarActions[i + 1]?.has_permission\r\n \"\r\n class=\"\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\r\n <i class=\"bi bi-x-circle\"></i> Clear Selection\r\n </button>\r\n </div>\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 * dataSetLength\"></div>\r\n </div> -->\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div\r\n class=\"d-flex justify-content-between\"\r\n *ngIf=\"hasScroll\"\r\n >\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)=\"onCenterBodyScroll($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 - 10\"></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\"\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-fff]=\"\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-fff]=\"\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\r\n [style.height.px]=\"footerRowHeight\"\r\n class=\"border-top\"\r\n [style.backgroundColor]=\"footerRowBackgroundColor\"\r\n >\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"separator\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results:\r\n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\r\n paginationConfig.page * paginationConfig.limit <\r\n paginationConfig.totalResults\r\n ? paginationConfig.page * paginationConfig.limit\r\n : paginationConfig.totalResults\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)=\"\r\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\r\n \"\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 align-items-center 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)=\"\r\n openThreeDotsMenu($event, child);\r\n openFilteronThreeDotsClick(child)\r\n \"\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)=\"\r\n openThreeDotsMenu($event, child);\r\n isThreeDotsFilterOpen = false\r\n \"\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 [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: child,\r\n isNestedTable: false,\r\n section: sections\r\n }\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)=\"\r\n $event.stopPropagation();\r\n onResizeColumn($event, child)\r\n \"\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)]=\"child.filterValue\"\r\n (ngModelChange)=\"onFilterChange(child)\"\r\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\r\n [readonly]=\"\r\n child?.type == 'dropdown' || child?.type == 'image'\r\n \"\r\n [class.disabled-search-input]=\"\r\n child?.type == 'dropdown' || child?.type == 'image'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n openFilterFromDisabledSearchedInput(child)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\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 [class.pe-none]=\"child?.type == 'image'\"\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\r\n class=\"group-column-wrapper\"\r\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\r\n >\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 align-items-center\"\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)=\"\r\n openThreeDotsMenu($event, col);\r\n openFilteronThreeDotsClick(col)\r\n \"\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 <!-- Ascending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + '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 cursor-pointer\"\r\n (click)=\"sortDesc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\r\n ></span>\r\n\r\n <!-- Descending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-desc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortAsc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n isThreeDotsFilterOpen = false\r\n \"\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 [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: false,\r\n section: sections\r\n }\r\n \"\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)=\"\r\n $event.stopPropagation(); onResizeColumn($event, col)\r\n \"\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 [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image'\r\n \"\r\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\r\n (click)=\"\r\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\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 [class.pe-none]=\"col?.type == 'image'\"\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 let-isTotalRow=\"isTotalRow\"\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 d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [class.border-below]=\"section !== 'center'\"\r\n [style.width]=\"\r\n section === 'center'\r\n ? (centerScrollableBody?.scrollWidth ?? 0) + '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]=\"55\"\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 [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\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 [style.color]=\"checkboxesColor\"\r\n >\r\n <input\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"getGroupCheckedState(row) === true\"\r\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\r\n (change)=\"selectGroupRow($event, row)\"\r\n />\r\n\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 [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\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 * 30 : 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 align-items-center d-flex\"\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\" [@slideToggle]>\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 isTotalRow: isTotalRow\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\r\n class=\"d-flex\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\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=\"\r\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\r\n \"\r\n [ngStyle]=\"{\r\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\r\n ? null\r\n : getBackgroundColor(row, isEven, section)\r\n }\"\r\n [class.selected-cell]=\"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 <span\r\n (click)=\"toggleDetailRowExpand(row)\"\r\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\r\n class=\"data-grid-svg-icon filter-icon-wrapper\"\r\n [inlineSVG]=\"\r\n isDetailsExpanded(row)\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)\"\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': getBackgroundColor(row, isEven, section)\r\n }\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row)\"\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': getBackgroundColor(row, isEven, section)\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]=\"55\"\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 [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\r\n </div>\r\n <div\r\n class=\"border-below\"\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 && showCheckboxes\"\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 [style.minHeight.px]=\"rowHeight - 1\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\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 isTotalRow: isTotalRow\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 *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\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 isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\r\n class=\"accordion-details center-section\"\r\n style=\"\r\n max-height: 350px;\r\n overflow-y: hidden;\r\n overflow-x: auto;\r\n scrollbar-width: thin;\r\n \"\r\n #nestedTable\r\n [style.width]=\"\r\n hasRightPinnedColumns\r\n ? '100%'\r\n : hasVerticalScroll\r\n ? 'calc(100% - 12px)'\r\n : '100%'\r\n \"\r\n >\r\n <ng-container *ngIf=\"gridType == 'Assets'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"gridType == 'Tasks'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n taskManagementTemplate;\r\n context: { taskDetails: row }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\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 let-isTotalRow=\"isTotalRow\"\r\n>\r\n <div\r\n #cellContainer\r\n (click)=\"\r\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\r\n \"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative data-grid-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.fontSize.px]=\"bodyTextFontsSize\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, false, cellContainer)\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 tabindex=\"-1\"\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\r\n class=\"table-cell\"\r\n [class.active-for-editing]=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n getNestedValue(row, col.field)?.length <= 50)\r\n \"\r\n >\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n (getNestedValue(row, col.field)?.length <= 50 &&\r\n !expandedCells.size));\r\n else viewMode\r\n \"\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 editing-dropdown-search-input\">\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 (mousedown)=\"$event.stopPropagation()\"\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); editingKey = null\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center deopdown-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 cursor-pointer\"\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 <cdk-virtual-scroll-viewport \r\n itemSize=\"35\" \r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\r\n *cdkVirtualFor=\"\r\n let option of col.column_dropdown_value \r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\r\n [for]=\"col.field + '-' + (option.value || option)\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\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-content-between align-items-center w-100 overflow-hidden\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Field icon (for Tasks grid) -->\r\n <ng-container\r\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\r\n >\r\n <span\r\n class=\"cursor-pointer me-2\"\r\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n [inlineSVG]=\"iconMap[col.field](row, col)\"\r\n ></span>\r\n </ng-container>\r\n\r\n <!-- \u2705 Custom cell renderer support -->\r\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\r\n <ng-container\r\n [cellRenderInit]=\"col.cellRenderer\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col?.field)\"\r\n (cellEvent)=\"onCellEvent($event)\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\r\n <ng-template #defaultCell>\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"getCellTitle(row, col)\"\r\n >\r\n <!-- Normal cell -->\r\n <ng-container\r\n *ngIf=\"\r\n col.type !== 'image' &&\r\n col.field != 'image' &&\r\n col.field != 'invoice.invoice_image' &&\r\n !isTotalRow\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{getCellTitle(row, col)}}\r\n </ng-container>\r\n\r\n <!-- Total row -->\r\n <ng-container *ngIf=\"isTotalRow\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n\r\n <!-- Invoice Image -->\r\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\r\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\r\n <span\r\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(getNestedValue(row, col.field)) +\r\n '.svg'\r\n \"\r\n ></span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Image cell -->\r\n <ng-container *ngIf=\"col.type == 'image' && !isTotalRow\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: { row: row, col: col }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <span\r\n *ngIf=\"\r\n (!col?.cellRenderer && showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50 && col.type !== 'image') ||\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 </ng-template>\r\n <!-- Expand / Collapse icon -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100 expanded-box\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\r\n [class.invisible]=\"!showDetailsBox\"\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 </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template\r\n #columnMenu\r\n let-col=\"col\"\r\n let-isNestedTable=\"isNestedTable\"\r\n let-columns=\"columns\"\r\n let-section=\"section\"\r\n>\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n [style.color]=\"headerTextColor\"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'left',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'right',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n null,\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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 [class.disable-sorting]=\"!col.is_groupable\"\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\r\n @slideToggle\r\n *ngIf=\"isThreeDotsFilterOpen\"\r\n class=\"three-dots-col-menu position-relative\"\r\n [style.right.px]=\"section == 'right' ? null : col.width - 45\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n >\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<!-- 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 class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n\r\n <div class=\"form-check mb-1 mt-2 ps-4 ms-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 ps-1\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById;\r\n let i = index\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </div> -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"filter-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1\"\r\n *cdkVirtualFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"option?.id ?? option?._id ?? option\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label fw-semibold\"\r\n [for]=\"option?.id ?? option?._id ?? option\"\r\n >\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\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 custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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)]=\"firstValue\"\r\n #filterMenueTextchInput\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n\r\n <div class=\"form-group mb-3 d-flex flex-row\">\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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=\"Second Value\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\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.disabled]=\"(!currentFilterSelectedIds!.size && !firstValue) || (condition !== 'none' && !secondValue)\"\r\n [class.pe-none]=\"(!currentFilterSelectedIds!.size && !firstValue) || (condition !== 'none' && !secondValue)\"\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"applyDropdownFilter()\"\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: 30px\"\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<!-- 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 d-none\"\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 mt-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\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\" *ngIf=\"showColumnsGrouping\">\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 <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% - 70px); 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 </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\r\n class=\"column-group d-flex align-items-center mb-2\"\r\n *ngIf=\"col.type !== 'image'\"\r\n >\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\" *ngIf=\"col.type !== 'image'\">\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)]=\"sideNestedFilterSearch\"\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 : sideNestedFilterSearch : 'value'\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 <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value'\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\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 </cdk-virtual-scroll-viewport>\r\n\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)=\"applySideFilter(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\" \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-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\"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <div\r\n class=\"form-group mb-3 d-flex flex-row muted\"\r\n style=\"font-size: 14px\"\r\n >\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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\r\n class=\"nnonem-check-label mb-0 mt-1\"\r\n for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <ng-container\r\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\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\"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\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(); removeSideFilter(col)\"\r\n >\r\n <span>Clear</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applySideFilter(col)\"\r\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n >\r\n <span style=\"margin-top: -1px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100 d-none\">\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 cdkDragHandle\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 [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 align-items-center 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 [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image'\r\n \"\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 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 class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Side Menu</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showSideMenu\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Filter Row</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showFilterRow\"\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 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 text-primary\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update 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\r\n class=\" pb-5 overflow-auto\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\r\n >\r\n <div\r\n class=\"cursor-pointer\"\r\n (click)=\"\r\n clearAllFilters();\r\n openIndex = null;\r\n temp_state.id = '';\r\n activeTopButton = '';\r\n curretaTablePresetForUpdate = null\r\n \"\r\n >\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n ></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=\"\r\n let table of filteredList;\r\n let i = index;\r\n trackBy: trackByTable\r\n \"\r\n >\r\n <!-- Item -->\r\n <div\r\n (click)=\"\r\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\r\n \"\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table); openIndex = null\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"\r\n (table?.is_temp && !temp_state.id) ||\r\n temp_state.id == table.id\r\n \"\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_default\"\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\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\r\n {{\r\n table?.config?.filterNames?.length > 25 \r\n ? (table?.config?.filterNames | slice:0:25) + '...'\r\n : table?.config?.filterNames\r\n }}\r\n ({{ table?.config?.totalCount }})\r\n </small>\r\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_default\"\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_default\">\r\n <div\r\n class=\"dropdown-wrapper\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"btn-icon muted-text\"\r\n (click)=\"toggleMenu(i, $event)\"\r\n aria-haspopup=\"true\"\r\n [attr.aria-expanded]=\"openIndex === i\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </button>\r\n\r\n <!-- menu -->\r\n <ul\r\n *ngIf=\"openIndex === i\"\r\n class=\"custom-dropdown-menu\"\r\n role=\"menu\"\r\n >\r\n <li role=\"none\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item\"\r\n (click)=\"\r\n actionPreset(table, 'setPreset'); temp_state.id = ''\r\n \"\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 </button>\r\n </li>\r\n\r\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item text-danger\"\r\n (click)=\"table.confirmDelete = true\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </button>\r\n </li>\r\n\r\n <li\r\n role=\"none\"\r\n *ngIf=\"table.confirmDelete\"\r\n class=\"confirm-block\"\r\n >\r\n <div class=\"px-3 py-2 text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete <br /><b\r\n >\u201C{{ table?.name }}\u201D</b\r\n >?\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"table.confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\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\">\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </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\" *ngIf=\"isTablePresetNotChanged\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\r\n >Update Preset</span\r\n >\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 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=\"overflow: auto; scrollbar-width: thin\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\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 class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"hide_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"show_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\r\n Show/Hide All \r\n </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 actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\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 && col.type !== 'image'\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 actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 210px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\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 border\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n <div>\r\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalAnd\"\r\n >AND</label\r\n >\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalNone\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\r\n <div class=\"mb-2 mt-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm border\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n </ng-container>\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 [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\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 [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\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\">Apply</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 [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\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 [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\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 {{\r\n item?.department_name ||\r\n item?.roleName ||\r\n item?.full_name ||\r\n \"-\"\r\n }}\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 (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\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 </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 w-100 cell-content image-placeholder\"\r\n [title]=\"row?.full_name || row?.name || 'N/A'\"\r\n >\r\n <ng-container\r\n *ngIf=\"\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice?.invoice_image ||\r\n row?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span\r\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\"\r\n class=\"pic\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [src]=\"\r\n row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\r\n \"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n loading=\"lazy\"\r\n />\r\n </span>\r\n </ng-container>\r\n <!-- <div\r\n class=\"fullscreen-overlay\"\r\n *ngIf=\"fullscreenImage\"\r\n (click)=\"fullscreenImage = null\"\r\n >\r\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\r\n </div> -->\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(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 [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n {{ getInitials(row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\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 right-click-menu-icons 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\r\n<ng-template #nestedTableTemplate let-row>\r\n <div\r\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\r\n style=\"table-layout: fixed !important\"\r\n #nestedTableContainer\r\n >\r\n <thead\r\n #nestedHeader\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n >\r\n <div\r\n cdkDropList\r\n [cdkDropListData]=\"row?.detail.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\"\r\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n class=\"d-flex tr border-below\"\r\n >\r\n <div\r\n *ngFor=\"let col of row.detail.columns; let i = index\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n class=\"px-4 th\"\r\n [attr.field]=\"col.field\"\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n cdkDrag\r\n >\r\n <div\r\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\r\n >\r\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\r\n {{ col.header }}\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <span\r\n *ngIf=\"currentSubSortColumn == col.field\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (col?.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 ms-2 start-50\"\r\n >\r\n </span>\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; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: true,\r\n columns: row?.detail.columns\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (click)=\"$event.stopPropagation()\"\r\n (mousedown)=\"\r\n $event.preventDefault();\r\n onResizeColumn($event, col);\r\n $event.stopPropagation()\r\n \"\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 <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 + '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 </div>\r\n </div>\r\n </thead>\r\n <div\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <cdk-virtual-scroll-viewport\r\n [itemSize]=\"nestedTablerowHeight\"\r\n class=\"viewport\"\r\n [style.height.px]=\"\r\n (row?.detail?.result?.length < 5\r\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\r\n : 300) + (hasHorizontalScroll ? -12 : 1)\r\n \"\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <div\r\n class=\"cursor-pointer border-below d-flex tr\"\r\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.width.px]=\"nestedHeader?.offsetWidth\"\r\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n (contextmenu)=\"onRightClick($event, d)\"\r\n >\r\n <div\r\n class=\"px-4 py-0 td\"\r\n *ngFor=\"let col of previewNestedCols; let j = index\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n >\r\n <div\r\n [style.height.px]=\"nestedTablerowHeight - 1\"\r\n [style.max-width.px]=\"col?.width\"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\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(d, col.field) | date : dateFormat)\r\n : getNestedValue(d, col.field) || '-'\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{\r\n !isNestedValueArray(d, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(d, col.field))\r\n ? (getNestedValue(d, col.field) | date: dateFormat)\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n '-'))\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n (col.is_amount ? 0: '-'))\r\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\r\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\r\n '-')\r\n }}\r\n </ng-container>\r\n <ng-container *ngIf=\"false\">\r\n {{ getTotalAmount(col) }}\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: d,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #leftRightNestedPlaceholder let-row>\r\n <table\r\n class=\"nested-table table table-sm w-100 mb-0\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n [style.height.px]=\"\r\n gridType == 'Assets'\r\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\r\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\r\n \"\r\n >\r\n <!-- <div class=\"thead\">\r\n <div\r\n class=\"tr d-flex border-below\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\r\n </div>\r\n </div> -->\r\n <!-- <div class=\"tbody\">\r\n <div\r\n class=\"tr border-below\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n *ngFor=\"let _ of row?.detail?.result\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\r\n <span\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.max-width.px]=\"nestedTablerowHeight\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </table>\r\n</ng-template>\r\n\r\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\r\n <div\r\n class=\"p-4\"\r\n #taskManagementContainer\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n [style.fontFaimly]=\"fontFaimly\"\r\n >\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Description</div>\r\n <!-- <div class=\"item-content firstDiv\">\r\n {{ taskDetails.description }}\r\n </div> -->\r\n <p\r\n [style.fontSize]=\"bodyTextFontsSize\"\r\n class=\"item-content firstDiv taskDescription pe-4\"\r\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\r\n (click)=\"openFullImage($event)\"\r\n ></p>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Attachments</div>\r\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\r\n No Attachments found\r\n </h5>\r\n <div\r\n *ngIf=\"taskDetails?.attachments?.length\"\r\n class=\"item-content d-flex flex-wrap\"\r\n style=\"gap: 10px\"\r\n >\r\n <a\r\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\r\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\r\n >\r\n <span\r\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(attachement)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(attachement) +\r\n '.svg'\r\n \"\r\n >\r\n </span>\r\n </a>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">\r\n Comments ({{ taskDetails?.comments?.length }})\r\n </div>\r\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\r\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\r\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\r\n <div class=\"d-flex align-items-center pe-3\">\r\n <img\r\n class=\"pic image-input-wrapper\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n *ngIf=\"comment?.comment_by.logo\"\r\n src=\"{{ comment?.comment_by.logo }}\"\r\n alt=\"{{ comment.comment_by.full_name }}\"\r\n />\r\n <!-- <app-default-image-placeholder *ngIf=\"!comment?.comment_by.logo\" title=\"{{ comment.comment_by.full_name }}\" [name]=\"comment.comment_by.full_name\"></app-default-image-placeholder> -->\r\n <span\r\n *ngIf=\"!comment?.comment_by.logo\"\r\n [ngClass]=\"getDynamicClass(comment.comment_by.full_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 title=\"{{ comment.comment_by.full_name }}\"\r\n >\r\n {{ getInitials(comment.comment_by.full_name) }}\r\n </span>\r\n </div>\r\n <div>\r\n <div class=\"comment-author fs-14px\">\r\n {{ comment?.comment_by.full_name }}\r\n </div>\r\n <div\r\n class=\"comment-content forCommentImg\"\r\n [innerHTML]=\"getSafeComment(comment.comment)\"\r\n ></div>\r\n <div class=\"comment-timestamp\">\r\n {{ comment.comment_date | date }}\r\n </div>\r\n <div class=\"comment-timestamp\">\r\n Replies: ({{ comment.replies.length }})\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;position:relative}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:80px;font-weight:600}.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;margin-right:4px}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0}.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{-webkit-user-select:none;user-select:none;display:flex}.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:#fff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.toggle-icon.rotate{transform:rotate(90deg)}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:absolute;right:200px;z-index:1050;background-color:#fff;border-radius:8px!important;cursor:default}.bg-fff{background-color:#fff}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important;display:flex!important;align-items:center!important}.global-search span{margin-top:-4px!important}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.dropdown-menu{background-color:#fff!important;border:1px solid #d9d9db!important;border-radius:8px!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0;background-color:#fff}.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;background:#fff;border-radius:8px!important}.actions-dropdown,.table-layout,.custom-menu,.dropdown-menu{background:#fff;border-radius:8px!important;border:1px solid #ccc!important;background-color:#fff}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0}.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-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell{font-weight:600}.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;display:flex;justify-content:center;z-index:1000}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.cell .badge-secondary{color:#6c757d;background-color:#f1f3f5;border:1px solid #6c757d}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.border-left{border-left:1px solid #d9d9db}.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 .center-section .table .tbody .tr:hover .td{background-color:#f0f8ff!important}.editing-dropdown-search-input input:focus{border:1px solid #86b7fe!important}.nested-table .thead{position:sticky;top:0}.dropdown-wrapper{position:relative;display:inline-block}.btn-icon{background:transparent;border:0;padding:.25rem .5rem;cursor:pointer}.custom-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:200px;list-style:none;margin:0;padding:.25rem 0;background:#fff!important;border:1px solid rgba(0,0,0,.08);box-shadow:0 6px 18px #00000014;border-radius:.35rem;z-index:1200}.custom-dropdown-menu .dropdown-item{display:block;width:100%;padding:.5rem 1rem;text-align:left;background:transparent;border:none}.custom-dropdown-menu .dropdown-item:hover{background:#00000008}.confirm-block{padding:0}.center-nested-table .tr:hover .td{background-color:#f0f8ff}.table ::ng-deep .cdk-drag-placeholder{background-color:#fff!important}.assets-pic{border-radius:8px!important}.fullscreen-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000c;display:flex;align-items:center;justify-content:center;z-index:1000;cursor:zoom-out}.fullscreen-img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 15px #00000080}.position-sticky{z-index:2}.viewport{display:block!important;overflow:visible!important}.nested-table ::ng-deep .cdk-virtual-scroll-content-wrapper{padding:0!important}.nested-table ::ng-deep .cdk-virtual-scroll-viewport{overflow-x:hidden!important}.disabled-search-input{background-color:#f5f5f5;cursor:pointer!important}.right-click-menu-icons ::ng-deep svg path{stroke-width:2!important}.loader{animation:rotate 1s infinite;height:50px;width:50px}.loader:before,.loader:after{border-radius:50%;content:\"\";display:block;height:20px;width:20px}.loader:before{animation:ball1 1s infinite;background-color:#fff;box-shadow:30px 0 #ff3d00;margin-bottom:10px}.loader:after{animation:ball2 1s infinite;background-color:#ff3d00;box-shadow:30px 0 #fff}@keyframes rotate{0%{transform:rotate(0) scale(.8)}50%{transform:rotate(360deg) scale(1.2)}to{transform:rotate(720deg) scale(.8)}}@keyframes ball1{0%{box-shadow:30px 0 #ff3d00}50%{box-shadow:0 0 #ff3d00;margin-bottom:0;transform:translate(15px,15px)}to{box-shadow:30px 0 #ff3d00;margin-bottom:10px}}@keyframes ball2{0%{box-shadow:30px 0 #fff}50%{box-shadow:0 0 #fff;margin-top:-20px;transform:translate(15px,15px)}to{box-shadow:30px 0 #fff;margin-top:0}}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{opacity:.7!important}.action-button{background-color:#6f61cf!important;color:#fff!important;border-radius:6px!important;font-weight:500!important;margin-top:-4px}.action-button:hover{background-color:#6a5fb3!important}.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}::ng-deep .nav-tabs .nav-link{border:none!important;border-bottom:2px solid transparent!important;border-radius:0!important;background:transparent!important}::ng-deep .nav-tabs .nav-link:hover,::ng-deep .nav-tabs .nav-link:focus{border:none!important;border-bottom:2px solid transparent!important;outline:none!important;background:transparent!important}::ng-deep .nav-tabs .nav-link.active{border:none!important;border-bottom:2px solid var(--bs-primary)!important;background:transparent!important;color:var(--bs-primary)!important}.open-top{top:-150%!important}.muted{color:#7a7a7a!important}.item-title{font-size:1.2em;font-weight:700;margin-bottom:10px}.item-image{width:100%;border-radius:10px}.comment{display:flex;align-items:center;margin-bottom:10px}.comment-avatar{width:40px;height:40px;border-radius:50%;margin-right:10px}.comment-author{font-weight:700}.comment-content{font-size:.9em;line-height:1.4}.comment-timestamp{font-size:.8em;color:#888;margin-left:auto}.des_low{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:242px;display:block;text-transform:capitalize!important}.firstDiv{word-break:break-word;overflow-wrap:break-word;white-space:normal}.container{display:flex;flex-wrap:wrap;margin:20px;gap:20px;background-color:#fff;padding:20px;border-radius:10px}.item{width:calc(33.33% - 20px);background-color:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 5px #0000001a}.forCommentImg{width:70px;border-radius:16px;margin:8px 0;cursor:pointer}.image-modal img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 4px 10px #00000080}.full-image-modal{position:fixed;background:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.full-image-modal .full-image{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 10px #fff3}.item-content{font-size:14px;line-height:1.5;max-height:220px;overflow-y:auto}.image-modal.full-image-modal{position:fixed;width:100vw;height:100vh;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:9999;overflow:hidden;cursor:zoom-out}.image-modal.full-image-modal img{border-radius:8px;box-shadow:0 4px 20px #0006;object-fit:contain;transition:transform .3s ease}.image-modal.full-image-modal img:hover{transform:scale(1.02)}::ng-deep .custom-overlay-wrapper .custom-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:9999}::ng-deep .custom-overlay-wrapper .custom-modal{background:#fff;border-radius:12px;box-shadow:0 8px 25px #0003;width:360px;max-width:90%;padding:24px;text-align:center;animation:fadeInScale .25s ease}::ng-deep .custom-overlay-wrapper .custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}::ng-deep .custom-overlay-wrapper .modal-actions{display:flex;justify-content:center;gap:12px}::ng-deep .custom-overlay-wrapper .modal-actions button{min-width:90px;padding:8px 14px;border-radius:6px;border:none;font-weight:500;cursor:pointer;transition:background-color .2s ease}::ng-deep .custom-overlay-wrapper .btn-confirm{background-color:#007bff;color:#fff}::ng-deep .custom-overlay-wrapper .btn-confirm:hover{background-color:#0069d9}::ng-deep .custom-overlay-wrapper .btn-cancel{background-color:#e4e4e4;color:#333}::ng-deep .custom-overlay-wrapper .btn-cancel:hover{background-color:#d6d6d6}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.clear-btn{background:linear-gradient(135deg,#f53545,#f53545);border:none;color:#fff;font-size:13px;padding:3px 6px;border-radius:20px;font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px #ff5f6d66;position:relative;bottom:4px}.clear-btn:hover{transform:translateY(-2px);box-shadow:0 4px 10px #ff5f6d99;background:linear-gradient(135deg,#f53545,#f53545)}.clear-btn i{font-size:16px;vertical-align:middle}.cell-editin-dropdown .deopdown-item{width:100%!important;box-shadow:none!important;border-radius:4px;cursor:pointer;padding-block:8px!important}.cell-editin-dropdown .deopdown-item:hover{background-color:#f1f1f1}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i6.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i6.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.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: i8.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i8.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i9.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i9.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: i10.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "directive", type: i11.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i11.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i11.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CellRenderInitDirective, selector: "[cellRenderInit]", inputs: ["cellRenderInit", "rowData", "colData", "cellValue"], outputs: ["cellEvent"] }, { kind: "pipe", type: i6.SlicePipe, name: "slice" }, { kind: "pipe", type: i6.DatePipe, name: "date" }, { kind: "pipe", type: FilterPipe, name: "filter" }], animations: [
5971
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DataGridComponent, selector: "data-grid", inputs: { rowAnimation: "rowAnimation", paginationConfig: "paginationConfig", dataSet: "dataSet", columns: "columns", rowHeight: "rowHeight", headerRowHeight: "headerRowHeight", showVerticalBorder: "showVerticalBorder", evenRowsBackgroundColor: "evenRowsBackgroundColor", oddRowsBackgroundColor: "oddRowsBackgroundColor", headerBackgroundColor: "headerBackgroundColor", checkboxesBackgroundColor: "checkboxesBackgroundColor", showColumnsGrouping: "showColumnsGrouping", rowHoverColor: "rowHoverColor", leftPinnedBackgroundColor: "leftPinnedBackgroundColor", bodyBackgroundColor: "bodyBackgroundColor", rightPinnedBackgroundColor: "rightPinnedBackgroundColor", sidemenuBackgroundColor: "sidemenuBackgroundColor", bodyTextColor: "bodyTextColor", headerTextColor: "headerTextColor", checkboxesColor: "checkboxesColor", headerTextFontsSize: "headerTextFontsSize", bodyTextFontsSize: "bodyTextFontsSize", headerFontWeight: "headerFontWeight", bodyFontWeight: "bodyFontWeight", checkedRowBackgroundColor: "checkedRowBackgroundColor", dropdownsBackgroundColor: "dropdownsBackgroundColor", footerRowBackgroundColor: "footerRowBackgroundColor", footerRowHeight: "footerRowHeight", topGroupedBadgesBackgroundColor: "topGroupedBadgesBackgroundColor", showRowsGrouping: "showRowsGrouping", showFilterRow: "showFilterRow", fontFaimly: "fontFaimly", showSideMenu: "showSideMenu", footerPadding: "footerPadding", topFilterRowHeight: "topFilterRowHeight", rowShadingEnabled: "rowShadingEnabled", showSerialNumber: "showSerialNumber", singleSpaAssetsPath: "singleSpaAssetsPath", filtersConfig: "filtersConfig", loading: "loading", verticalScrollbarWidth: "verticalScrollbarWidth", horizintalScrollbarWidth: "horizintalScrollbarWidth", showCellDetailsBox: "showCellDetailsBox", dateFormat: "dateFormat", tableSearch: "tableSearch", actions: "actions", config: "config", showTaskbar: "showTaskbar", tableName: "tableName", listingType: "listingType", checkboxState: "checkboxState", taskbarActions: "taskbarActions", sortingConfig: "sortingConfig", tableFilterViewId: "tableFilterViewId", selectedTableLayout: "selectedTableLayout", closeDropdown: "closeDropdown", globalSearchText: "globalSearchText", nestedTablerowFontsize: "nestedTablerowFontsize", nestedTableHeaderRowHeight: "nestedTableHeaderRowHeight", nestedTablerowHeight: "nestedTablerowHeight", gridType: "gridType", currencySymbol: "currencySymbol", currencyFormat: "currencyFormat", leftPinnedBoxshadow: "leftPinnedBoxshadow", rightPinnedBoxshadow: "rightPinnedBoxshadow", selectedRowsBackgroundColor: "selectedRowsBackgroundColor", nestedTableHeaderBackgroundColor: "nestedTableHeaderBackgroundColor", nestedTableRowBackgroundColor: "nestedTableRowBackgroundColor", tableView: "tableView", buttons: "buttons", keepMultipleExpandedDetails: "keepMultipleExpandedDetails", showTotalAmountRow: "showTotalAmountRow", enableGlobalSearch: "enableGlobalSearch", tableType: "tableType", enableExport: "enableExport", showFullScreenButton: "showFullScreenButton", enableCut: "enableCut", tabs: "tabs", showCheckboxes: "showCheckboxes", resetAllFilters: "resetAllFilters", columnThreedotsMunuConfig: "columnThreedotsMunuConfig" }, outputs: { changeLayout: "changeLayout", customCellEvent: "customCellEvent", filterOptions: "filterOptions", genericEvent: "genericEvent", tablePresetConfig: "tablePresetConfig", sortingOrderOptions: "sortingOrderOptions", createUpdateConfigListing: "createUpdateConfigListing" }, 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: "nestedHeader", first: true, predicate: ["nestedHeader"], descendants: true }, { propertyName: "dataGridContainer", first: true, predicate: ["dataGridContainer"], descendants: true }, { propertyName: "taskManagementContainer", first: true, predicate: ["taskManagementContainer"], descendants: true }, { propertyName: "nestedTableContainer", first: true, predicate: ["nestedTableContainer"], 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: "textAreadInput", first: true, predicate: ["textAreadInput"], descendants: true }, { propertyName: "nestedTable", first: true, predicate: ["nestedTable"], descendants: true }, { propertyName: "fullscreenImageTemplate", first: true, predicate: ["fullscreenImageTemplate"], descendants: true }, { propertyName: "cellHosts", predicate: CellHostDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"position-relative h-100\">\r\n <div\r\n class=\"d-flex justify-content-between mb-2 align-items-center position-relative\"\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\r\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\r\n <span\r\n *ngFor=\"let tab of tabs; let i = index\"\r\n (click)=\"setActiveTab(tab)\"\r\n class=\"nav-link cursor-pointer\"\r\n [class.active]=\"activeTab == tab\"\r\n >\r\n {{ tab }}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"global-search\" [style.width.px]=\"350\">\r\n <span\r\n *ngIf=\"enableGlobalSearch\"\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 *ngIf=\"enableGlobalSearch\"\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Type to search, then press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n (input)=\"onSearchInput($event)\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n <ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\r\n *ngIf=\"button?.has_permission\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button button-small btn border border-primary btn-active-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\r\n \"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span\r\n class=\"label-hidden text-white\"\r\n [class.ms-0]=\"button.is_showIcon\"\r\n >{{ button?.name }}</span\r\n >\r\n </a>\r\n </div>\r\n </ng-container>\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\r\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\r\n <a\r\n *ngIf=\"!isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Minimise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n <a\r\n *ngIf=\"isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Maximise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\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>\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 [style.backgroundColor]=\"bodyBackgroundColor\"\r\n id=\"data-grid-main-container\"\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\r\n class=\"d-flex gap-2 align-items-center\"\r\n [style.color]=\"headerTextColor\"\r\n >\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 <div\r\n cdkDropListOrientation=\"horizontal\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onGroupReorder($event)\"\r\n class=\"d-flex\"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragLockAxis]=\"'x'\"\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n class=\"d-flex align-items-center\"\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-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\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>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\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\r\n class=\"data-grid-header left-pinned\"\r\n #leftPinnedHeader\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n >\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]=\"55\"\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\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\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 style=\"width: 16px; height: 16px\"\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 [style.backgroundColor]=\"headerBackgroundColor\"\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: 1px\"\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 *ngIf=\"!draggingInGroupArea\"\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)=\"onCenterBodyScroll($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)=\"\r\n openThreeDotsMenu($event, 'group');\r\n isThreeDotsFilterOpen = false\r\n \"\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)=\"\r\n $event.stopPropagation(); onResizeGroupBox($event)\r\n \"\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 === 'Assets' || gridType === 'Tasks'\"\r\n >\r\n </span>\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col);\r\n dragStartOnGroup(col);\r\n onDragStarted(col)\r\n \"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\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 *ngIf=\"!isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (draggingInGroupArea\r\n ? 'data-grid/icons/justify.svg'\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 >\r\n </span>\r\n <span\r\n *ngIf=\"isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\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 && !isOutsideContainer\"\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>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\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: 'right'\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 *ngIf=\"!draggingInGroupArea\"\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: 'right'\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 && !dataSetLoading\"\r\n >\r\n <!-- <div\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></div> -->\r\n <div>No Record Found</div>\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 || dataSetLoading\"\r\n style=\"\r\n z-index: 999;\r\n backdrop-filter: blur(1px);\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div class=\"spinner-border text-primary\" role=\"status\">\r\n <!-- <span class=\"loader\"></span> -->\r\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\r\n <!-- </div> -->\r\n </div>\r\n </div>\r\n\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 [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div\r\n [style.height.px]=\"\r\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\r\n \"\r\n ></div>\r\n <div [class.h-100]=\"originalDataSet.length < 8\">\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]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n\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 isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewLeftPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'left',\r\n isTotalRow: true\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=\"h-100\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n >\r\n <div [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\">\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 isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewCenterColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'center',\r\n isTotalRow: true\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 < 8\"\r\n [style.maxWidth.px]=\"\r\n isScrollbarVisible\r\n ? rightPinnedHeader.offsetWidth - 15\r\n : rightPinnedHeader.offsetWidth\r\n \"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100 h-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewRightPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'right',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n style=\"top: auto; left: auto\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n fullscreenImage = null;\r\n cdr.detectChanges()\r\n \"\r\n [style.width.px]=\"dataGridContainer.offsetWidth\"\r\n [style.height.px]=\"\r\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\r\n \"\r\n class=\"image-modal full-image-modal\"\r\n *ngIf=\"fullscreenImage\"\r\n >\r\n <img\r\n (click)=\"$event.stopPropagation()\"\r\n [src]=\"fullscreenImage\"\r\n alt=\"Fullscreen Image\"\r\n />\r\n </div>\r\n <div\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar w-100\"\r\n [style.bottom.px]=\"85\"\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 {{\r\n paginationConfig.totalResults ||\r\n config?.paginationParams?.totalItems\r\n }}\r\n Total\r\n </span>\r\n <div class=\"action-buttons d-flex align-items-center\">\r\n <ng-container\r\n *ngFor=\"let action of taskbarActions; let i = index\"\r\n >\r\n <ng-container *ngIf=\"action?.has_permission\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action?.actionName)\"\r\n >{{ action?.actionName }}</span\r\n >\r\n <span\r\n *ngIf=\"\r\n taskbarActions.length > 1 &&\r\n i !== taskbarActions.length - 1 &&\r\n taskbarActions[i + 1]?.has_permission\r\n \"\r\n class=\"\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\r\n <i class=\"bi bi-x-circle\"></i> Clear Selection\r\n </button>\r\n </div>\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 * dataSetLength\"></div>\r\n </div> -->\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div\r\n class=\"d-flex justify-content-between\"\r\n *ngIf=\"hasScroll\"\r\n >\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)=\"onCenterBodyScroll($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 - 10\"></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\"\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-fff]=\"\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-fff]=\"\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\r\n [style.height.px]=\"footerRowHeight\"\r\n class=\"border-top\"\r\n [style.backgroundColor]=\"footerRowBackgroundColor\"\r\n >\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"separator\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results:\r\n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\r\n paginationConfig.page * paginationConfig.limit <\r\n paginationConfig.totalResults\r\n ? paginationConfig.page * paginationConfig.limit\r\n : paginationConfig.totalResults\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)=\"\r\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\r\n \"\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 align-items-center 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)=\"\r\n openThreeDotsMenu($event, child);\r\n openFilteronThreeDotsClick(child)\r\n \"\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)=\"\r\n openThreeDotsMenu($event, child);\r\n isThreeDotsFilterOpen = false\r\n \"\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 [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: child,\r\n isNestedTable: false,\r\n section: sections\r\n }\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)=\"\r\n $event.stopPropagation();\r\n onResizeColumn($event, child)\r\n \"\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)]=\"child.filterValue\"\r\n (ngModelChange)=\"onFilterChange(child)\"\r\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\r\n [readonly]=\"\r\n child?.type == 'dropdown' || child?.type == 'image'\r\n \"\r\n [class.disabled-search-input]=\"\r\n child?.type == 'dropdown' || child?.type == 'image'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n openFilterFromDisabledSearchedInput(child)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\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 [class.pe-none]=\"child?.type == 'image'\"\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\r\n class=\"group-column-wrapper\"\r\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\r\n >\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 align-items-center\"\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)=\"\r\n openThreeDotsMenu($event, col);\r\n openFilteronThreeDotsClick(col)\r\n \"\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 <!-- Ascending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + '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 cursor-pointer\"\r\n (click)=\"sortDesc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\r\n ></span>\r\n\r\n <!-- Descending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-desc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortAsc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n isThreeDotsFilterOpen = false\r\n \"\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 [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: false,\r\n section: sections\r\n }\r\n \"\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)=\"\r\n $event.stopPropagation(); onResizeColumn($event, col)\r\n \"\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 [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image'\r\n \"\r\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\r\n (click)=\"\r\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\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 [class.pe-none]=\"col?.type == 'image'\"\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 let-isTotalRow=\"isTotalRow\"\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 d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [class.border-below]=\"section !== 'center'\"\r\n [style.width]=\"\r\n section === 'center'\r\n ? (centerScrollableBody?.scrollWidth ?? 0) + '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]=\"55\"\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 [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\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 [style.color]=\"checkboxesColor\"\r\n >\r\n <input\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"getGroupCheckedState(row) === true\"\r\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\r\n (change)=\"selectGroupRow($event, row)\"\r\n />\r\n\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 [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\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 * 30 : 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 align-items-center d-flex\"\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\" [@slideToggle]>\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 isTotalRow: isTotalRow\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\r\n class=\"d-flex\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\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=\"\r\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\r\n \"\r\n [ngStyle]=\"{\r\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\r\n ? null\r\n : getBackgroundColor(row, isEven, section)\r\n }\"\r\n [class.selected-cell]=\"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 <span\r\n (click)=\"toggleDetailRowExpand(row)\"\r\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\r\n class=\"data-grid-svg-icon filter-icon-wrapper\"\r\n [inlineSVG]=\"\r\n isDetailsExpanded(row)\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)\"\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': getBackgroundColor(row, isEven, section)\r\n }\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row)\"\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': getBackgroundColor(row, isEven, section)\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]=\"55\"\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 [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\r\n </div>\r\n <div\r\n class=\"border-below\"\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 && showCheckboxes\"\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 [style.minHeight.px]=\"rowHeight - 1\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\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 isTotalRow: isTotalRow\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 *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\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 isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\r\n class=\"accordion-details center-section\"\r\n style=\"\r\n max-height: 350px;\r\n overflow-y: hidden;\r\n overflow-x: auto;\r\n scrollbar-width: thin;\r\n \"\r\n #nestedTable\r\n [style.width]=\"\r\n hasRightPinnedColumns\r\n ? '100%'\r\n : hasVerticalScroll\r\n ? 'calc(100% - 12px)'\r\n : '100%'\r\n \"\r\n >\r\n <ng-container *ngIf=\"gridType == 'Assets'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"gridType == 'Tasks'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n taskManagementTemplate;\r\n context: { taskDetails: row }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\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 let-isTotalRow=\"isTotalRow\"\r\n>\r\n <div\r\n #cellContainer\r\n (click)=\"\r\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\r\n \"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative data-grid-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.fontSize.px]=\"bodyTextFontsSize\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, false, cellContainer)\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 tabindex=\"-1\"\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\r\n class=\"table-cell\"\r\n [class.active-for-editing]=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n getNestedValue(row, col.field)?.length <= 50)\r\n \"\r\n >\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n (getNestedValue(row, col.field)?.length <= 50 &&\r\n !expandedCells.size));\r\n else viewMode\r\n \"\r\n >\r\n\r\n <ng-container *ngIf=\"col.cellEditor; else builtInEditors\">\r\n <ng-container\r\n [cellEditor]=\"col.cellEditor\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col.field)\"\r\n (editorEvent)=\"finishEdit($event)\"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #builtInEditors>\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 editing-dropdown-search-input\" *ngIf=\"col?.column_dropdown_value?.length > 5\">\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 (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n <cdk-virtual-scroll-viewport \r\n itemSize=\"35\" \r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n [class.selected]=\"getNestedValue(row, col.field) == option?.value || getNestedValue(row, col.field) == option\"\r\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\r\n *cdkVirtualFor=\"\r\n let option of col.column_dropdown_value \r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\r\n >\r\n <label\r\n \r\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\r\n [for]=\"col.field + '-' + (option.value || option)\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\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 </ng-template>\r\n\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100 overflow-hidden\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Field icon (for Tasks grid) -->\r\n <ng-container\r\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\r\n >\r\n <span\r\n class=\"cursor-pointer me-2\"\r\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n [inlineSVG]=\"iconMap[col.field](row, col)\"\r\n ></span>\r\n </ng-container>\r\n\r\n <!-- \u2705 Custom cell renderer support -->\r\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\r\n <ng-container\r\n [cellRenderInit]=\"col.cellRenderer\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col?.field)\"\r\n (cellEvent)=\"onCellEvent($event)\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\r\n <ng-template #defaultCell>\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"getCellTitle(row, col)\"\r\n >\r\n <!-- Normal cell -->\r\n <ng-container\r\n *ngIf=\"\r\n col.type !== 'image' &&\r\n col.field != 'image' &&\r\n col.field != 'invoice.invoice_image' &&\r\n !isTotalRow\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{getCellTitle(row, col)}}\r\n </ng-container>\r\n\r\n <!-- Total row -->\r\n <ng-container *ngIf=\"isTotalRow\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n\r\n <!-- Invoice Image -->\r\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\r\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\r\n <span\r\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(getNestedValue(row, col.field)) +\r\n '.svg'\r\n \"\r\n ></span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Image cell -->\r\n <ng-container *ngIf=\"col.type == 'image' && !isTotalRow\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: { row: row, col: col }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <span\r\n *ngIf=\"\r\n (!col?.cellRenderer && showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50 && col.type !== 'image') ||\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 </ng-template>\r\n <!-- Expand / Collapse icon -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100 expanded-box\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\r\n [class.invisible]=\"!showDetailsBox\"\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 </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template\r\n #columnMenu\r\n let-col=\"col\"\r\n let-isNestedTable=\"isNestedTable\"\r\n let-columns=\"columns\"\r\n let-section=\"section\"\r\n>\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n [style.color]=\"headerTextColor\"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'left',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'right',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n null,\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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 [class.disable-sorting]=\"!col.is_groupable\"\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\r\n @slideToggle\r\n *ngIf=\"isThreeDotsFilterOpen\"\r\n class=\"three-dots-col-menu position-relative\"\r\n [style.right.px]=\"section == 'right' ? null : col.width - 45\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n >\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<!-- 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 class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n\r\n <div class=\"form-check mb-1 mt-2 ps-4 ms-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 ps-1\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById;\r\n let i = index\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </div> -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"filter-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"option?.id ?? option?._id ?? option\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label fw-semibold\"\r\n [for]=\"option?.id ?? option?._id ?? option\"\r\n >\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\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 custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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)]=\"firstValue\"\r\n #filterMenueTextchInput\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n\r\n <div class=\"form-group mb-3 d-flex flex-row\">\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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=\"Second Value\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\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: 30px\"\r\n (click)=\"applyDropdownFilter()\"\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: 30px\"\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<!-- 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 d-none\"\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 mt-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\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\" *ngIf=\"showColumnsGrouping\">\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 <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% - 70px); 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 </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\r\n class=\"column-group d-flex align-items-center mb-2\"\r\n *ngIf=\"col.type !== 'image'\"\r\n >\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\" *ngIf=\"col.type !== 'image'\">\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)]=\"sideNestedFilterSearch\"\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 : sideNestedFilterSearch : 'value'\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 <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value'\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\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 </cdk-virtual-scroll-viewport>\r\n\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)=\"applySideFilter(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\" \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-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\"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <div\r\n class=\"form-group mb-3 d-flex flex-row muted\"\r\n style=\"font-size: 14px\"\r\n >\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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\r\n class=\"nnonem-check-label mb-0 mt-1\"\r\n for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <ng-container\r\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\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\"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\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(); removeSideFilter(col)\"\r\n >\r\n <span>Clear</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applySideFilter(col)\"\r\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n >\r\n <span style=\"margin-top: -1px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100 d-none\">\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 cdkDragHandle\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 [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 align-items-center 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 [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image'\r\n \"\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 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 class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Side Menu</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showSideMenu\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Filter Row</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showFilterRow\"\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 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 text-primary\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update 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\r\n class=\" pb-5 overflow-auto\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\r\n >\r\n <div\r\n class=\"cursor-pointer\"\r\n (click)=\"\r\n clearAllFilters();\r\n openIndex = null;\r\n temp_state.id = '';\r\n activeTopButton = '';\r\n curretaTablePresetForUpdate = null\r\n \"\r\n >\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n ></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=\"\r\n let table of filteredList;\r\n let i = index;\r\n trackBy: trackByTable\r\n \"\r\n >\r\n <!-- Item -->\r\n <div\r\n (click)=\"\r\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\r\n \"\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table); openIndex = null\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"\r\n (table?.is_temp && !temp_state.id) ||\r\n temp_state.id == table.id\r\n \"\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_default\"\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\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\r\n {{\r\n table?.config?.filterNames?.length > 25 \r\n ? (table?.config?.filterNames | slice:0:25) + '...'\r\n : table?.config?.filterNames\r\n }}\r\n ({{ table?.config?.totalCount }})\r\n </small>\r\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_default\"\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_default\">\r\n <div\r\n class=\"dropdown-wrapper\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"btn-icon muted-text\"\r\n (click)=\"toggleMenu(i, $event)\"\r\n aria-haspopup=\"true\"\r\n [attr.aria-expanded]=\"openIndex === i\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </button>\r\n\r\n <!-- menu -->\r\n <ul\r\n *ngIf=\"openIndex === i\"\r\n class=\"custom-dropdown-menu\"\r\n role=\"menu\"\r\n >\r\n <li role=\"none\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item\"\r\n (click)=\"\r\n actionPreset(table, 'setPreset'); temp_state.id = ''\r\n \"\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 </button>\r\n </li>\r\n\r\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item text-danger\"\r\n (click)=\"table.confirmDelete = true\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </button>\r\n </li>\r\n\r\n <li\r\n role=\"none\"\r\n *ngIf=\"table.confirmDelete\"\r\n class=\"confirm-block\"\r\n >\r\n <div class=\"px-3 py-2 text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete <br /><b\r\n >\u201C{{ table?.name }}\u201D</b\r\n >?\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"table.confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\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\">\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </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\" *ngIf=\"isTablePresetNotChanged\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\r\n >Update Preset</span\r\n >\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 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 d-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=\"overflow: auto; scrollbar-width: thin\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\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 class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"hide_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"show_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\r\n Show/Hide All \r\n </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 actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\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 && col.type !== 'image'\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 actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 210px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\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 border\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n <div>\r\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalAnd\"\r\n >AND</label\r\n >\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalNone\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\r\n <div class=\"mb-2 mt-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm border\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n </ng-container>\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 [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\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 [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\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\">Apply</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 [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\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 [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\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 {{\r\n item?.department_name ||\r\n item?.roleName ||\r\n item?.full_name ||\r\n \"-\"\r\n }}\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 (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\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 </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 w-100 cell-content image-placeholder\"\r\n [title]=\"row?.full_name || row?.name || 'N/A'\"\r\n >\r\n <ng-container\r\n *ngIf=\"\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice?.invoice_image ||\r\n row?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span\r\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\"\r\n class=\"pic\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [src]=\"\r\n row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\r\n \"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n loading=\"lazy\"\r\n />\r\n </span>\r\n </ng-container>\r\n <!-- <div\r\n class=\"fullscreen-overlay\"\r\n *ngIf=\"fullscreenImage\"\r\n (click)=\"fullscreenImage = null\"\r\n >\r\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\r\n </div> -->\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(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 [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n {{ getInitials(row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\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 right-click-menu-icons 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\r\n<ng-template #nestedTableTemplate let-row>\r\n <div\r\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\r\n style=\"table-layout: fixed !important\"\r\n #nestedTableContainer\r\n >\r\n <thead\r\n #nestedHeader\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n >\r\n <div\r\n cdkDropList\r\n [cdkDropListData]=\"row?.detail.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\"\r\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n class=\"d-flex tr border-below\"\r\n >\r\n <div\r\n *ngFor=\"let col of row.detail.columns; let i = index\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n class=\"px-4 th\"\r\n [attr.field]=\"col.field\"\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n cdkDrag\r\n >\r\n <div\r\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\r\n >\r\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\r\n {{ col.header }}\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <span\r\n *ngIf=\"currentSubSortColumn == col.field\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (col?.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 ms-2 start-50\"\r\n >\r\n </span>\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; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: true,\r\n columns: row?.detail.columns\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (click)=\"$event.stopPropagation()\"\r\n (mousedown)=\"\r\n $event.preventDefault();\r\n onResizeColumn($event, col);\r\n $event.stopPropagation()\r\n \"\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 <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 + '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 </div>\r\n </div>\r\n </thead>\r\n <div\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <cdk-virtual-scroll-viewport\r\n [itemSize]=\"nestedTablerowHeight\"\r\n class=\"viewport\"\r\n [style.height.px]=\"\r\n (row?.detail?.result?.length < 5\r\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\r\n : 300) + (hasHorizontalScroll ? -12 : 1)\r\n \"\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <div\r\n class=\"cursor-pointer border-below d-flex tr\"\r\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.width.px]=\"nestedHeader?.offsetWidth\"\r\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n (contextmenu)=\"onRightClick($event, d)\"\r\n >\r\n <div\r\n class=\"px-4 py-0 td\"\r\n *ngFor=\"let col of previewNestedCols; let j = index\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n >\r\n <div\r\n [style.height.px]=\"nestedTablerowHeight - 1\"\r\n [style.max-width.px]=\"col?.width\"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\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(d, col.field) | date : dateFormat)\r\n : getNestedValue(d, col.field) || '-'\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{\r\n !isNestedValueArray(d, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(d, col.field))\r\n ? (getNestedValue(d, col.field) | date: dateFormat)\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n '-'))\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n (col.is_amount ? 0: '-'))\r\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\r\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\r\n '-')\r\n }}\r\n </ng-container>\r\n <ng-container *ngIf=\"false\">\r\n {{ getTotalAmount(col) }}\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: d,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #leftRightNestedPlaceholder let-row>\r\n <table\r\n class=\"nested-table table table-sm w-100 mb-0\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n [style.height.px]=\"\r\n gridType == 'Assets'\r\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\r\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\r\n \"\r\n >\r\n <!-- <div class=\"thead\">\r\n <div\r\n class=\"tr d-flex border-below\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\r\n </div>\r\n </div> -->\r\n <!-- <div class=\"tbody\">\r\n <div\r\n class=\"tr border-below\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n *ngFor=\"let _ of row?.detail?.result\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\r\n <span\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.max-width.px]=\"nestedTablerowHeight\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </table>\r\n</ng-template>\r\n\r\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\r\n <div\r\n class=\"p-4\"\r\n #taskManagementContainer\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n [style.fontFaimly]=\"fontFaimly\"\r\n >\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Description</div>\r\n <!-- <div class=\"item-content firstDiv\">\r\n {{ taskDetails.description }}\r\n </div> -->\r\n <p\r\n [style.fontSize]=\"bodyTextFontsSize\"\r\n class=\"item-content firstDiv taskDescription pe-4\"\r\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\r\n (click)=\"openFullImage($event)\"\r\n ></p>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Attachments</div>\r\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\r\n No Attachments found\r\n </h5>\r\n <div\r\n *ngIf=\"taskDetails?.attachments?.length\"\r\n class=\"item-content d-flex flex-wrap\"\r\n style=\"gap: 10px\"\r\n >\r\n <a\r\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\r\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\r\n >\r\n <span\r\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(attachement)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(attachement) +\r\n '.svg'\r\n \"\r\n >\r\n </span>\r\n </a>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">\r\n Comments ({{ taskDetails?.comments?.length }})\r\n </div>\r\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\r\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\r\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\r\n <div class=\"d-flex align-items-center pe-3\">\r\n <img\r\n class=\"pic image-input-wrapper\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n *ngIf=\"comment?.comment_by.logo\"\r\n src=\"{{ comment?.comment_by.logo }}\"\r\n alt=\"{{ comment.comment_by.full_name }}\"\r\n />\r\n <!-- <app-default-image-placeholder *ngIf=\"!comment?.comment_by.logo\" title=\"{{ comment.comment_by.full_name }}\" [name]=\"comment.comment_by.full_name\"></app-default-image-placeholder> -->\r\n <span\r\n *ngIf=\"!comment?.comment_by.logo\"\r\n [ngClass]=\"getDynamicClass(comment.comment_by.full_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 title=\"{{ comment.comment_by.full_name }}\"\r\n >\r\n {{ getInitials(comment.comment_by.full_name) }}\r\n </span>\r\n </div>\r\n <div>\r\n <div class=\"comment-author fs-14px\">\r\n {{ comment?.comment_by.full_name }}\r\n </div>\r\n <div\r\n class=\"comment-content forCommentImg\"\r\n [innerHTML]=\"getSafeComment(comment.comment)\"\r\n ></div>\r\n <div class=\"comment-timestamp\">\r\n {{ comment.comment_date | date }}\r\n </div>\r\n <div class=\"comment-timestamp\">\r\n Replies: ({{ comment.replies.length }})\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;position:relative}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:80px;font-weight:600}.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;margin-right:4px}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0}.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{-webkit-user-select:none;user-select:none;display:flex}.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:#fff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.toggle-icon.rotate{transform:rotate(90deg)}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:absolute;right:200px;z-index:1050;background-color:#fff;border-radius:8px!important;cursor:default}.bg-fff{background-color:#fff}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important;display:flex!important;align-items:center!important}.global-search span{margin-top:-4px!important}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.dropdown-menu{background-color:#fff!important;border:1px solid #d9d9db!important;border-radius:8px!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0;background-color:#fff}.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;background:#fff;border-radius:8px!important}.actions-dropdown,.table-layout,.custom-menu,.dropdown-menu{background:#fff;border-radius:8px!important;border:1px solid #ccc!important;background-color:#fff}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0}.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;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026;max-height:400px;overflow:auto}.full-text-box ul{max-height:400px}.full-text-content{border-radius:8px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell{font-weight:600}.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;display:flex;justify-content:center;z-index:1000}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.cell .badge-secondary{color:#6c757d;background-color:#f1f3f5;border:1px solid #6c757d}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.border-left{border-left:1px solid #d9d9db}.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 .center-section .table .tbody .tr:hover .td{background-color:#f0f8ff!important}.editing-dropdown-search-input input:focus{border:1px solid #86b7fe!important}.nested-table .thead{position:sticky;top:0}.dropdown-wrapper{position:relative;display:inline-block}.btn-icon{background:transparent;border:0;padding:.25rem .5rem;cursor:pointer}.custom-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:200px;list-style:none;margin:0;padding:.25rem 0;background:#fff!important;border:1px solid rgba(0,0,0,.08);box-shadow:0 6px 18px #00000014;border-radius:.35rem;z-index:1200}.custom-dropdown-menu .dropdown-item{display:block;width:100%;padding:.5rem 1rem;text-align:left;background:transparent;border:none}.custom-dropdown-menu .dropdown-item:hover{background:#00000008}.cell-editing-dropdown-menu .dropdown-item{width:99%}.cell-editing-dropdown-menu .selected{background-color:#f0f8ff}.confirm-block{padding:0}.center-nested-table .tr:hover .td{background-color:#f0f8ff}.table ::ng-deep .cdk-drag-placeholder{background-color:#fff!important}.assets-pic{border-radius:8px!important}.fullscreen-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000c;display:flex;align-items:center;justify-content:center;z-index:1000;cursor:zoom-out}.fullscreen-img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 15px #00000080}.position-sticky{z-index:2}.viewport{display:block!important;overflow:visible!important}.nested-table ::ng-deep .cdk-virtual-scroll-content-wrapper{padding:0!important}.nested-table ::ng-deep .cdk-virtual-scroll-viewport{overflow-x:hidden!important}.disabled-search-input{background-color:#f5f5f5;cursor:pointer!important}.right-click-menu-icons ::ng-deep svg path{stroke-width:2!important}.loader{animation:rotate 1s infinite;height:50px;width:50px}.loader:before,.loader:after{border-radius:50%;content:\"\";display:block;height:20px;width:20px}.loader:before{animation:ball1 1s infinite;background-color:#fff;box-shadow:30px 0 #ff3d00;margin-bottom:10px}.loader:after{animation:ball2 1s infinite;background-color:#ff3d00;box-shadow:30px 0 #fff}@keyframes rotate{0%{transform:rotate(0) scale(.8)}50%{transform:rotate(360deg) scale(1.2)}to{transform:rotate(720deg) scale(.8)}}@keyframes ball1{0%{box-shadow:30px 0 #ff3d00}50%{box-shadow:0 0 #ff3d00;margin-bottom:0;transform:translate(15px,15px)}to{box-shadow:30px 0 #ff3d00;margin-bottom:10px}}@keyframes ball2{0%{box-shadow:30px 0 #fff}50%{box-shadow:0 0 #fff;margin-top:-20px;transform:translate(15px,15px)}to{box-shadow:30px 0 #fff;margin-top:0}}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{opacity:.7!important}.action-button{background-color:#6f61cf!important;color:#fff!important;border-radius:6px!important;font-weight:500!important;margin-top:-4px}.action-button:hover{background-color:#6a5fb3!important}.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}::ng-deep .nav-tabs .nav-link{border:none!important;border-bottom:2px solid transparent!important;border-radius:0!important;background:transparent!important}::ng-deep .nav-tabs .nav-link:hover,::ng-deep .nav-tabs .nav-link:focus{border:none!important;border-bottom:2px solid transparent!important;outline:none!important;background:transparent!important}::ng-deep .nav-tabs .nav-link.active{border:none!important;border-bottom:2px solid var(--bs-primary)!important;background:transparent!important;color:var(--bs-primary)!important}.open-top{top:-150%!important}.muted{color:#7a7a7a!important}.item-title{font-size:1.2em;font-weight:700;margin-bottom:10px}.item-image{width:100%;border-radius:10px}.comment{display:flex;align-items:center;margin-bottom:10px}.comment-avatar{width:40px;height:40px;border-radius:50%;margin-right:10px}.comment-author{font-weight:700}.comment-content{font-size:.9em;line-height:1.4}.comment-timestamp{font-size:.8em;color:#888;margin-left:auto}.des_low{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:242px;display:block;text-transform:capitalize!important}.firstDiv{word-break:break-word;overflow-wrap:break-word;white-space:normal}.container{display:flex;flex-wrap:wrap;margin:20px;gap:20px;background-color:#fff;padding:20px;border-radius:10px}.item{width:calc(33.33% - 20px);background-color:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 5px #0000001a}.forCommentImg{width:70px;border-radius:16px;margin:8px 0;cursor:pointer}.image-modal img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 4px 10px #00000080}.full-image-modal{position:fixed;background:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.full-image-modal .full-image{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 10px #fff3}.item-content{font-size:14px;line-height:1.5;max-height:220px;overflow-y:auto}.image-modal.full-image-modal{position:fixed;width:100vw;height:100vh;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:9999;overflow:hidden;cursor:zoom-out}.image-modal.full-image-modal img{border-radius:8px;box-shadow:0 4px 20px #0006;object-fit:contain;transition:transform .3s ease}.image-modal.full-image-modal img:hover{transform:scale(1.02)}::ng-deep .custom-overlay-wrapper .custom-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:9999}::ng-deep .custom-overlay-wrapper .custom-modal{background:#fff;border-radius:12px;box-shadow:0 8px 25px #0003;width:360px;max-width:90%;padding:24px;text-align:center;animation:fadeInScale .25s ease}::ng-deep .custom-overlay-wrapper .custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}::ng-deep .custom-overlay-wrapper .modal-actions{display:flex;justify-content:center;gap:12px}::ng-deep .custom-overlay-wrapper .modal-actions button{min-width:90px;padding:8px 14px;border-radius:6px;border:none;font-weight:500;cursor:pointer;transition:background-color .2s ease}::ng-deep .custom-overlay-wrapper .btn-confirm{background-color:#007bff;color:#fff}::ng-deep .custom-overlay-wrapper .btn-confirm:hover{background-color:#0069d9}::ng-deep .custom-overlay-wrapper .btn-cancel{background-color:#e4e4e4;color:#333}::ng-deep .custom-overlay-wrapper .btn-cancel:hover{background-color:#d6d6d6}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.clear-btn{background:linear-gradient(135deg,#f53545,#f53545);border:none;color:#fff;font-size:13px;padding:3px 6px;border-radius:20px;font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px #ff5f6d66;position:relative;bottom:4px}.clear-btn:hover{transform:translateY(-2px);box-shadow:0 4px 10px #ff5f6d99;background:linear-gradient(135deg,#f53545,#f53545)}.clear-btn i{font-size:16px;vertical-align:middle}.cell-editin-dropdown .deopdown-item{width:100%!important;box-shadow:none!important;border-radius:4px;cursor:pointer;padding-block:8px!important}.cell-editin-dropdown .deopdown-item:hover{background-color:#f1f1f1}\n"], dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i6.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i6.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.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: i8.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i8.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i9.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i9.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: i10.InlineSVGDirective, selector: "[inlineSVG]", inputs: ["inlineSVG", "resolveSVGUrl", "replaceContents", "prepend", "injectComponent", "cacheSVG", "setSVGAttributes", "removeSVGAttributes", "forceEvalStyles", "evalScripts", "fallbackImgUrl", "fallbackSVG", "onSVGLoaded"], outputs: ["onSVGInserted", "onSVGFailed"] }, { kind: "directive", type: i11.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i11.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i11.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CellRenderInitDirective, selector: "[cellRenderInit]", inputs: ["cellRenderInit", "rowData", "colData", "cellValue"], outputs: ["cellEvent"] }, { kind: "directive", type: CellEditorDirective, selector: "[cellEditor]", inputs: ["cellEditor", "rowData", "colData", "cellValue"], outputs: ["editorEvent"] }, { kind: "pipe", type: i6.SlicePipe, name: "slice" }, { kind: "pipe", type: i6.DatePipe, name: "date" }, { kind: "pipe", type: FilterPipe, name: "filter" }], animations: [
5854
5972
  trigger('accordionToggle', [
5855
5973
  state('collapsed', style({ height: '0px', overflow: 'unset' })),
5856
5974
  state('expanded', style({ height: '*', overflow: 'unset' })),
@@ -6066,7 +6184,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6066
6184
  ], { optional: true })
6067
6185
  ]),
6068
6186
  ])
6069
- ], template: "<div class=\"position-relative h-100\">\r\n <div\r\n class=\"d-flex justify-content-between mb-2 align-items-center position-relative\"\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\r\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\r\n <span\r\n *ngFor=\"let tab of tabs; let i = index\"\r\n (click)=\"setActiveTab(tab)\"\r\n class=\"nav-link cursor-pointer\"\r\n [class.active]=\"activeTab == tab\"\r\n >\r\n {{ tab }}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"global-search\" [style.width.px]=\"350\">\r\n <span\r\n *ngIf=\"enableGlobalSearch\"\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 *ngIf=\"enableGlobalSearch\"\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Type to search, then press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n (input)=\"onSearchInput($event)\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n <ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\r\n *ngIf=\"button?.has_permission\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button button-small btn border border-primary btn-active-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\r\n \"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span\r\n class=\"label-hidden text-white\"\r\n [class.ms-0]=\"button.is_showIcon\"\r\n >{{ button?.name }}</span\r\n >\r\n </a>\r\n </div>\r\n </ng-container>\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\r\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\r\n <a\r\n *ngIf=\"!isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Minimise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n <a\r\n *ngIf=\"isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Maximise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\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>\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 [style.backgroundColor]=\"bodyBackgroundColor\"\r\n id=\"data-grid-main-container\"\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\r\n class=\"d-flex gap-2 align-items-center\"\r\n [style.color]=\"headerTextColor\"\r\n >\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 <div\r\n cdkDropListOrientation=\"horizontal\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onGroupReorder($event)\"\r\n class=\"d-flex\"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragLockAxis]=\"'x'\"\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n class=\"d-flex align-items-center\"\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-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\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>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\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\r\n class=\"data-grid-header left-pinned\"\r\n #leftPinnedHeader\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n >\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]=\"55\"\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\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\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 style=\"width: 16px; height: 16px\"\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 [style.backgroundColor]=\"headerBackgroundColor\"\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: 1px\"\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 *ngIf=\"!draggingInGroupArea\"\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)=\"onCenterBodyScroll($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)=\"\r\n openThreeDotsMenu($event, 'group');\r\n isThreeDotsFilterOpen = false\r\n \"\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)=\"\r\n $event.stopPropagation(); onResizeGroupBox($event)\r\n \"\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 === 'Assets' || gridType === 'Tasks'\"\r\n >\r\n </span>\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col);\r\n dragStartOnGroup(col);\r\n onDragStarted(col)\r\n \"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\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 *ngIf=\"!isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (draggingInGroupArea\r\n ? 'data-grid/icons/justify.svg'\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 >\r\n </span>\r\n <span\r\n *ngIf=\"isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\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 && !isOutsideContainer\"\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>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\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: 'right'\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 *ngIf=\"!draggingInGroupArea\"\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: 'right'\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 && !dataSetLoading\"\r\n >\r\n <!-- <div\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></div> -->\r\n <div>No Record Found</div>\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 || dataSetLoading\"\r\n style=\"\r\n z-index: 999;\r\n backdrop-filter: blur(1px);\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div class=\"spinner-border text-primary\" role=\"status\">\r\n <!-- <span class=\"loader\"></span> -->\r\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\r\n <!-- </div> -->\r\n </div>\r\n </div>\r\n\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 [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div\r\n [style.height.px]=\"\r\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\r\n \"\r\n ></div>\r\n <div [class.h-100]=\"originalDataSet.length < 8\">\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]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n\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 isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewLeftPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'left',\r\n isTotalRow: true\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=\"h-100\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container *ngIf=\"!loading && !dataSetLoading\">\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 isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewCenterColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'center',\r\n isTotalRow: true\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 < 8\"\r\n [style.maxWidth.px]=\"\r\n isScrollbarVisible\r\n ? rightPinnedHeader.offsetWidth - 15\r\n : rightPinnedHeader.offsetWidth\r\n \"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100 h-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewRightPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'right',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n style=\"top: auto; left: auto\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n fullscreenImage = null;\r\n cdr.detectChanges()\r\n \"\r\n [style.width.px]=\"dataGridContainer.offsetWidth\"\r\n [style.height.px]=\"\r\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\r\n \"\r\n class=\"image-modal full-image-modal\"\r\n *ngIf=\"fullscreenImage\"\r\n >\r\n <img\r\n (click)=\"$event.stopPropagation()\"\r\n [src]=\"fullscreenImage\"\r\n alt=\"Fullscreen Image\"\r\n />\r\n </div>\r\n <div\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar w-100\"\r\n [style.bottom.px]=\"85\"\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 {{\r\n paginationConfig.totalResults ||\r\n config?.paginationParams?.totalItems\r\n }}\r\n Total\r\n </span>\r\n <div class=\"action-buttons d-flex align-items-center\">\r\n <ng-container\r\n *ngFor=\"let action of taskbarActions; let i = index\"\r\n >\r\n <ng-container *ngIf=\"action?.has_permission\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action?.actionName)\"\r\n >{{ action?.actionName }}</span\r\n >\r\n <span\r\n *ngIf=\"\r\n taskbarActions.length > 1 &&\r\n i !== taskbarActions.length - 1 &&\r\n taskbarActions[i + 1]?.has_permission\r\n \"\r\n class=\"\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\r\n <i class=\"bi bi-x-circle\"></i> Clear Selection\r\n </button>\r\n </div>\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 * dataSetLength\"></div>\r\n </div> -->\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div\r\n class=\"d-flex justify-content-between\"\r\n *ngIf=\"hasScroll\"\r\n >\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)=\"onCenterBodyScroll($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 - 10\"></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\"\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-fff]=\"\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-fff]=\"\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\r\n [style.height.px]=\"footerRowHeight\"\r\n class=\"border-top\"\r\n [style.backgroundColor]=\"footerRowBackgroundColor\"\r\n >\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"separator\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results:\r\n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\r\n paginationConfig.page * paginationConfig.limit <\r\n paginationConfig.totalResults\r\n ? paginationConfig.page * paginationConfig.limit\r\n : paginationConfig.totalResults\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)=\"\r\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\r\n \"\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 align-items-center 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)=\"\r\n openThreeDotsMenu($event, child);\r\n openFilteronThreeDotsClick(child)\r\n \"\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)=\"\r\n openThreeDotsMenu($event, child);\r\n isThreeDotsFilterOpen = false\r\n \"\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 [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: child,\r\n isNestedTable: false,\r\n section: sections\r\n }\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)=\"\r\n $event.stopPropagation();\r\n onResizeColumn($event, child)\r\n \"\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)]=\"child.filterValue\"\r\n (ngModelChange)=\"onFilterChange(child)\"\r\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\r\n [readonly]=\"\r\n child?.type == 'dropdown' || child?.type == 'image'\r\n \"\r\n [class.disabled-search-input]=\"\r\n child?.type == 'dropdown' || child?.type == 'image'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n openFilterFromDisabledSearchedInput(child)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\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 [class.pe-none]=\"child?.type == 'image'\"\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\r\n class=\"group-column-wrapper\"\r\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\r\n >\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 align-items-center\"\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)=\"\r\n openThreeDotsMenu($event, col);\r\n openFilteronThreeDotsClick(col)\r\n \"\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 <!-- Ascending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + '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 cursor-pointer\"\r\n (click)=\"sortDesc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\r\n ></span>\r\n\r\n <!-- Descending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-desc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortAsc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n isThreeDotsFilterOpen = false\r\n \"\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 [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: false,\r\n section: sections\r\n }\r\n \"\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)=\"\r\n $event.stopPropagation(); onResizeColumn($event, col)\r\n \"\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 [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image'\r\n \"\r\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\r\n (click)=\"\r\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\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 [class.pe-none]=\"col?.type == 'image'\"\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 let-isTotalRow=\"isTotalRow\"\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 d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [class.border-below]=\"section !== 'center'\"\r\n [style.width]=\"\r\n section === 'center'\r\n ? (centerScrollableBody?.scrollWidth ?? 0) + '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]=\"55\"\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 [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\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 [style.color]=\"checkboxesColor\"\r\n >\r\n <input\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"getGroupCheckedState(row) === true\"\r\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\r\n (change)=\"selectGroupRow($event, row)\"\r\n />\r\n\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 [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\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 * 30 : 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 align-items-center d-flex\"\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\" [@slideToggle]>\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 isTotalRow: isTotalRow\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\r\n class=\"d-flex\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\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=\"\r\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\r\n \"\r\n [ngStyle]=\"{\r\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\r\n ? null\r\n : getBackgroundColor(row, isEven, section)\r\n }\"\r\n [class.selected-cell]=\"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 <span\r\n (click)=\"toggleDetailRowExpand(row)\"\r\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\r\n class=\"data-grid-svg-icon filter-icon-wrapper\"\r\n [inlineSVG]=\"\r\n isDetailsExpanded(row)\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)\"\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': getBackgroundColor(row, isEven, section)\r\n }\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row)\"\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': getBackgroundColor(row, isEven, section)\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]=\"55\"\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 [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\r\n </div>\r\n <div\r\n class=\"border-below\"\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 && showCheckboxes\"\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 [style.minHeight.px]=\"rowHeight - 1\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\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 isTotalRow: isTotalRow\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 *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\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 isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\r\n class=\"accordion-details center-section\"\r\n style=\"\r\n max-height: 350px;\r\n overflow-y: hidden;\r\n overflow-x: auto;\r\n scrollbar-width: thin;\r\n \"\r\n #nestedTable\r\n [style.width]=\"\r\n hasRightPinnedColumns\r\n ? '100%'\r\n : hasVerticalScroll\r\n ? 'calc(100% - 12px)'\r\n : '100%'\r\n \"\r\n >\r\n <ng-container *ngIf=\"gridType == 'Assets'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"gridType == 'Tasks'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n taskManagementTemplate;\r\n context: { taskDetails: row }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\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 let-isTotalRow=\"isTotalRow\"\r\n>\r\n <div\r\n #cellContainer\r\n (click)=\"\r\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\r\n \"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative data-grid-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.fontSize.px]=\"bodyTextFontsSize\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, false, cellContainer)\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 tabindex=\"-1\"\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\r\n class=\"table-cell\"\r\n [class.active-for-editing]=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n getNestedValue(row, col.field)?.length <= 50)\r\n \"\r\n >\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n (getNestedValue(row, col.field)?.length <= 50 &&\r\n !expandedCells.size));\r\n else viewMode\r\n \"\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 editing-dropdown-search-input\">\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 (mousedown)=\"$event.stopPropagation()\"\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); editingKey = null\r\n \"\r\n class=\"px-2 py-1 d-flex align-items-center deopdown-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 cursor-pointer\"\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 <cdk-virtual-scroll-viewport \r\n itemSize=\"35\" \r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\r\n *cdkVirtualFor=\"\r\n let option of col.column_dropdown_value \r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\r\n >\r\n <label\r\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\r\n [for]=\"col.field + '-' + (option.value || option)\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\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-content-between align-items-center w-100 overflow-hidden\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Field icon (for Tasks grid) -->\r\n <ng-container\r\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\r\n >\r\n <span\r\n class=\"cursor-pointer me-2\"\r\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n [inlineSVG]=\"iconMap[col.field](row, col)\"\r\n ></span>\r\n </ng-container>\r\n\r\n <!-- \u2705 Custom cell renderer support -->\r\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\r\n <ng-container\r\n [cellRenderInit]=\"col.cellRenderer\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col?.field)\"\r\n (cellEvent)=\"onCellEvent($event)\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\r\n <ng-template #defaultCell>\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"getCellTitle(row, col)\"\r\n >\r\n <!-- Normal cell -->\r\n <ng-container\r\n *ngIf=\"\r\n col.type !== 'image' &&\r\n col.field != 'image' &&\r\n col.field != 'invoice.invoice_image' &&\r\n !isTotalRow\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{getCellTitle(row, col)}}\r\n </ng-container>\r\n\r\n <!-- Total row -->\r\n <ng-container *ngIf=\"isTotalRow\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n\r\n <!-- Invoice Image -->\r\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\r\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\r\n <span\r\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(getNestedValue(row, col.field)) +\r\n '.svg'\r\n \"\r\n ></span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Image cell -->\r\n <ng-container *ngIf=\"col.type == 'image' && !isTotalRow\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: { row: row, col: col }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <span\r\n *ngIf=\"\r\n (!col?.cellRenderer && showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50 && col.type !== 'image') ||\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 </ng-template>\r\n <!-- Expand / Collapse icon -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100 expanded-box\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\r\n [class.invisible]=\"!showDetailsBox\"\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 </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template\r\n #columnMenu\r\n let-col=\"col\"\r\n let-isNestedTable=\"isNestedTable\"\r\n let-columns=\"columns\"\r\n let-section=\"section\"\r\n>\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n [style.color]=\"headerTextColor\"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'left',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'right',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n null,\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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 [class.disable-sorting]=\"!col.is_groupable\"\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\r\n @slideToggle\r\n *ngIf=\"isThreeDotsFilterOpen\"\r\n class=\"three-dots-col-menu position-relative\"\r\n [style.right.px]=\"section == 'right' ? null : col.width - 45\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n >\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<!-- 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 class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n\r\n <div class=\"form-check mb-1 mt-2 ps-4 ms-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 ps-1\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById;\r\n let i = index\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </div> -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"filter-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1\"\r\n *cdkVirtualFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"option?.id ?? option?._id ?? option\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label fw-semibold\"\r\n [for]=\"option?.id ?? option?._id ?? option\"\r\n >\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\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 custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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)]=\"firstValue\"\r\n #filterMenueTextchInput\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n\r\n <div class=\"form-group mb-3 d-flex flex-row\">\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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=\"Second Value\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\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.disabled]=\"(!currentFilterSelectedIds!.size && !firstValue) || (condition !== 'none' && !secondValue)\"\r\n [class.pe-none]=\"(!currentFilterSelectedIds!.size && !firstValue) || (condition !== 'none' && !secondValue)\"\r\n class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center w-100\"\r\n style=\"height: 30px\"\r\n (click)=\"applyDropdownFilter()\"\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: 30px\"\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<!-- 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 d-none\"\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 mt-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\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\" *ngIf=\"showColumnsGrouping\">\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 <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% - 70px); 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 </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\r\n class=\"column-group d-flex align-items-center mb-2\"\r\n *ngIf=\"col.type !== 'image'\"\r\n >\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\" *ngIf=\"col.type !== 'image'\">\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)]=\"sideNestedFilterSearch\"\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 : sideNestedFilterSearch : 'value'\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 <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value'\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\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 </cdk-virtual-scroll-viewport>\r\n\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)=\"applySideFilter(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\" \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-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\"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <div\r\n class=\"form-group mb-3 d-flex flex-row muted\"\r\n style=\"font-size: 14px\"\r\n >\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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\r\n class=\"nnonem-check-label mb-0 mt-1\"\r\n for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <ng-container\r\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\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\"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\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(); removeSideFilter(col)\"\r\n >\r\n <span>Clear</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applySideFilter(col)\"\r\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n >\r\n <span style=\"margin-top: -1px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100 d-none\">\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 cdkDragHandle\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 [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 align-items-center 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 [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image'\r\n \"\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 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 class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Side Menu</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showSideMenu\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Filter Row</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showFilterRow\"\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 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 text-primary\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update 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\r\n class=\" pb-5 overflow-auto\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\r\n >\r\n <div\r\n class=\"cursor-pointer\"\r\n (click)=\"\r\n clearAllFilters();\r\n openIndex = null;\r\n temp_state.id = '';\r\n activeTopButton = '';\r\n curretaTablePresetForUpdate = null\r\n \"\r\n >\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n ></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=\"\r\n let table of filteredList;\r\n let i = index;\r\n trackBy: trackByTable\r\n \"\r\n >\r\n <!-- Item -->\r\n <div\r\n (click)=\"\r\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\r\n \"\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table); openIndex = null\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"\r\n (table?.is_temp && !temp_state.id) ||\r\n temp_state.id == table.id\r\n \"\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_default\"\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\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\r\n {{\r\n table?.config?.filterNames?.length > 25 \r\n ? (table?.config?.filterNames | slice:0:25) + '...'\r\n : table?.config?.filterNames\r\n }}\r\n ({{ table?.config?.totalCount }})\r\n </small>\r\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_default\"\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_default\">\r\n <div\r\n class=\"dropdown-wrapper\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"btn-icon muted-text\"\r\n (click)=\"toggleMenu(i, $event)\"\r\n aria-haspopup=\"true\"\r\n [attr.aria-expanded]=\"openIndex === i\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </button>\r\n\r\n <!-- menu -->\r\n <ul\r\n *ngIf=\"openIndex === i\"\r\n class=\"custom-dropdown-menu\"\r\n role=\"menu\"\r\n >\r\n <li role=\"none\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item\"\r\n (click)=\"\r\n actionPreset(table, 'setPreset'); temp_state.id = ''\r\n \"\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 </button>\r\n </li>\r\n\r\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item text-danger\"\r\n (click)=\"table.confirmDelete = true\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </button>\r\n </li>\r\n\r\n <li\r\n role=\"none\"\r\n *ngIf=\"table.confirmDelete\"\r\n class=\"confirm-block\"\r\n >\r\n <div class=\"px-3 py-2 text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete <br /><b\r\n >\u201C{{ table?.name }}\u201D</b\r\n >?\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"table.confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\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\">\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </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\" *ngIf=\"isTablePresetNotChanged\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\r\n >Update Preset</span\r\n >\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 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=\"overflow: auto; scrollbar-width: thin\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\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 class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"hide_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"show_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\r\n Show/Hide All \r\n </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 actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\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 && col.type !== 'image'\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 actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 210px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\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 border\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n <div>\r\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalAnd\"\r\n >AND</label\r\n >\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalNone\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\r\n <div class=\"mb-2 mt-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm border\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n </ng-container>\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 [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\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 [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\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\">Apply</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 [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\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 [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\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 {{\r\n item?.department_name ||\r\n item?.roleName ||\r\n item?.full_name ||\r\n \"-\"\r\n }}\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 (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\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 </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 w-100 cell-content image-placeholder\"\r\n [title]=\"row?.full_name || row?.name || 'N/A'\"\r\n >\r\n <ng-container\r\n *ngIf=\"\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice?.invoice_image ||\r\n row?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span\r\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\"\r\n class=\"pic\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [src]=\"\r\n row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\r\n \"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n loading=\"lazy\"\r\n />\r\n </span>\r\n </ng-container>\r\n <!-- <div\r\n class=\"fullscreen-overlay\"\r\n *ngIf=\"fullscreenImage\"\r\n (click)=\"fullscreenImage = null\"\r\n >\r\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\r\n </div> -->\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(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 [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n {{ getInitials(row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\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 right-click-menu-icons 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\r\n<ng-template #nestedTableTemplate let-row>\r\n <div\r\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\r\n style=\"table-layout: fixed !important\"\r\n #nestedTableContainer\r\n >\r\n <thead\r\n #nestedHeader\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n >\r\n <div\r\n cdkDropList\r\n [cdkDropListData]=\"row?.detail.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\"\r\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n class=\"d-flex tr border-below\"\r\n >\r\n <div\r\n *ngFor=\"let col of row.detail.columns; let i = index\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n class=\"px-4 th\"\r\n [attr.field]=\"col.field\"\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n cdkDrag\r\n >\r\n <div\r\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\r\n >\r\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\r\n {{ col.header }}\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <span\r\n *ngIf=\"currentSubSortColumn == col.field\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (col?.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 ms-2 start-50\"\r\n >\r\n </span>\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; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: true,\r\n columns: row?.detail.columns\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (click)=\"$event.stopPropagation()\"\r\n (mousedown)=\"\r\n $event.preventDefault();\r\n onResizeColumn($event, col);\r\n $event.stopPropagation()\r\n \"\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 <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 + '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 </div>\r\n </div>\r\n </thead>\r\n <div\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <cdk-virtual-scroll-viewport\r\n [itemSize]=\"nestedTablerowHeight\"\r\n class=\"viewport\"\r\n [style.height.px]=\"\r\n (row?.detail?.result?.length < 5\r\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\r\n : 300) + (hasHorizontalScroll ? -12 : 1)\r\n \"\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <div\r\n class=\"cursor-pointer border-below d-flex tr\"\r\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.width.px]=\"nestedHeader?.offsetWidth\"\r\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n (contextmenu)=\"onRightClick($event, d)\"\r\n >\r\n <div\r\n class=\"px-4 py-0 td\"\r\n *ngFor=\"let col of previewNestedCols; let j = index\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n >\r\n <div\r\n [style.height.px]=\"nestedTablerowHeight - 1\"\r\n [style.max-width.px]=\"col?.width\"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\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(d, col.field) | date : dateFormat)\r\n : getNestedValue(d, col.field) || '-'\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{\r\n !isNestedValueArray(d, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(d, col.field))\r\n ? (getNestedValue(d, col.field) | date: dateFormat)\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n '-'))\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n (col.is_amount ? 0: '-'))\r\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\r\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\r\n '-')\r\n }}\r\n </ng-container>\r\n <ng-container *ngIf=\"false\">\r\n {{ getTotalAmount(col) }}\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: d,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #leftRightNestedPlaceholder let-row>\r\n <table\r\n class=\"nested-table table table-sm w-100 mb-0\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n [style.height.px]=\"\r\n gridType == 'Assets'\r\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\r\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\r\n \"\r\n >\r\n <!-- <div class=\"thead\">\r\n <div\r\n class=\"tr d-flex border-below\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\r\n </div>\r\n </div> -->\r\n <!-- <div class=\"tbody\">\r\n <div\r\n class=\"tr border-below\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n *ngFor=\"let _ of row?.detail?.result\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\r\n <span\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.max-width.px]=\"nestedTablerowHeight\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </table>\r\n</ng-template>\r\n\r\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\r\n <div\r\n class=\"p-4\"\r\n #taskManagementContainer\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n [style.fontFaimly]=\"fontFaimly\"\r\n >\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Description</div>\r\n <!-- <div class=\"item-content firstDiv\">\r\n {{ taskDetails.description }}\r\n </div> -->\r\n <p\r\n [style.fontSize]=\"bodyTextFontsSize\"\r\n class=\"item-content firstDiv taskDescription pe-4\"\r\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\r\n (click)=\"openFullImage($event)\"\r\n ></p>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Attachments</div>\r\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\r\n No Attachments found\r\n </h5>\r\n <div\r\n *ngIf=\"taskDetails?.attachments?.length\"\r\n class=\"item-content d-flex flex-wrap\"\r\n style=\"gap: 10px\"\r\n >\r\n <a\r\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\r\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\r\n >\r\n <span\r\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(attachement)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(attachement) +\r\n '.svg'\r\n \"\r\n >\r\n </span>\r\n </a>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">\r\n Comments ({{ taskDetails?.comments?.length }})\r\n </div>\r\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\r\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\r\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\r\n <div class=\"d-flex align-items-center pe-3\">\r\n <img\r\n class=\"pic image-input-wrapper\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n *ngIf=\"comment?.comment_by.logo\"\r\n src=\"{{ comment?.comment_by.logo }}\"\r\n alt=\"{{ comment.comment_by.full_name }}\"\r\n />\r\n <!-- <app-default-image-placeholder *ngIf=\"!comment?.comment_by.logo\" title=\"{{ comment.comment_by.full_name }}\" [name]=\"comment.comment_by.full_name\"></app-default-image-placeholder> -->\r\n <span\r\n *ngIf=\"!comment?.comment_by.logo\"\r\n [ngClass]=\"getDynamicClass(comment.comment_by.full_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 title=\"{{ comment.comment_by.full_name }}\"\r\n >\r\n {{ getInitials(comment.comment_by.full_name) }}\r\n </span>\r\n </div>\r\n <div>\r\n <div class=\"comment-author fs-14px\">\r\n {{ comment?.comment_by.full_name }}\r\n </div>\r\n <div\r\n class=\"comment-content forCommentImg\"\r\n [innerHTML]=\"getSafeComment(comment.comment)\"\r\n ></div>\r\n <div class=\"comment-timestamp\">\r\n {{ comment.comment_date | date }}\r\n </div>\r\n <div class=\"comment-timestamp\">\r\n Replies: ({{ comment.replies.length }})\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;position:relative}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:80px;font-weight:600}.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;margin-right:4px}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0}.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{-webkit-user-select:none;user-select:none;display:flex}.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:#fff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.toggle-icon.rotate{transform:rotate(90deg)}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:absolute;right:200px;z-index:1050;background-color:#fff;border-radius:8px!important;cursor:default}.bg-fff{background-color:#fff}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important;display:flex!important;align-items:center!important}.global-search span{margin-top:-4px!important}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.dropdown-menu{background-color:#fff!important;border:1px solid #d9d9db!important;border-radius:8px!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0;background-color:#fff}.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;background:#fff;border-radius:8px!important}.actions-dropdown,.table-layout,.custom-menu,.dropdown-menu{background:#fff;border-radius:8px!important;border:1px solid #ccc!important;background-color:#fff}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0}.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-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell{font-weight:600}.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;display:flex;justify-content:center;z-index:1000}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.cell .badge-secondary{color:#6c757d;background-color:#f1f3f5;border:1px solid #6c757d}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.border-left{border-left:1px solid #d9d9db}.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 .center-section .table .tbody .tr:hover .td{background-color:#f0f8ff!important}.editing-dropdown-search-input input:focus{border:1px solid #86b7fe!important}.nested-table .thead{position:sticky;top:0}.dropdown-wrapper{position:relative;display:inline-block}.btn-icon{background:transparent;border:0;padding:.25rem .5rem;cursor:pointer}.custom-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:200px;list-style:none;margin:0;padding:.25rem 0;background:#fff!important;border:1px solid rgba(0,0,0,.08);box-shadow:0 6px 18px #00000014;border-radius:.35rem;z-index:1200}.custom-dropdown-menu .dropdown-item{display:block;width:100%;padding:.5rem 1rem;text-align:left;background:transparent;border:none}.custom-dropdown-menu .dropdown-item:hover{background:#00000008}.confirm-block{padding:0}.center-nested-table .tr:hover .td{background-color:#f0f8ff}.table ::ng-deep .cdk-drag-placeholder{background-color:#fff!important}.assets-pic{border-radius:8px!important}.fullscreen-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000c;display:flex;align-items:center;justify-content:center;z-index:1000;cursor:zoom-out}.fullscreen-img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 15px #00000080}.position-sticky{z-index:2}.viewport{display:block!important;overflow:visible!important}.nested-table ::ng-deep .cdk-virtual-scroll-content-wrapper{padding:0!important}.nested-table ::ng-deep .cdk-virtual-scroll-viewport{overflow-x:hidden!important}.disabled-search-input{background-color:#f5f5f5;cursor:pointer!important}.right-click-menu-icons ::ng-deep svg path{stroke-width:2!important}.loader{animation:rotate 1s infinite;height:50px;width:50px}.loader:before,.loader:after{border-radius:50%;content:\"\";display:block;height:20px;width:20px}.loader:before{animation:ball1 1s infinite;background-color:#fff;box-shadow:30px 0 #ff3d00;margin-bottom:10px}.loader:after{animation:ball2 1s infinite;background-color:#ff3d00;box-shadow:30px 0 #fff}@keyframes rotate{0%{transform:rotate(0) scale(.8)}50%{transform:rotate(360deg) scale(1.2)}to{transform:rotate(720deg) scale(.8)}}@keyframes ball1{0%{box-shadow:30px 0 #ff3d00}50%{box-shadow:0 0 #ff3d00;margin-bottom:0;transform:translate(15px,15px)}to{box-shadow:30px 0 #ff3d00;margin-bottom:10px}}@keyframes ball2{0%{box-shadow:30px 0 #fff}50%{box-shadow:0 0 #fff;margin-top:-20px;transform:translate(15px,15px)}to{box-shadow:30px 0 #fff;margin-top:0}}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{opacity:.7!important}.action-button{background-color:#6f61cf!important;color:#fff!important;border-radius:6px!important;font-weight:500!important;margin-top:-4px}.action-button:hover{background-color:#6a5fb3!important}.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}::ng-deep .nav-tabs .nav-link{border:none!important;border-bottom:2px solid transparent!important;border-radius:0!important;background:transparent!important}::ng-deep .nav-tabs .nav-link:hover,::ng-deep .nav-tabs .nav-link:focus{border:none!important;border-bottom:2px solid transparent!important;outline:none!important;background:transparent!important}::ng-deep .nav-tabs .nav-link.active{border:none!important;border-bottom:2px solid var(--bs-primary)!important;background:transparent!important;color:var(--bs-primary)!important}.open-top{top:-150%!important}.muted{color:#7a7a7a!important}.item-title{font-size:1.2em;font-weight:700;margin-bottom:10px}.item-image{width:100%;border-radius:10px}.comment{display:flex;align-items:center;margin-bottom:10px}.comment-avatar{width:40px;height:40px;border-radius:50%;margin-right:10px}.comment-author{font-weight:700}.comment-content{font-size:.9em;line-height:1.4}.comment-timestamp{font-size:.8em;color:#888;margin-left:auto}.des_low{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:242px;display:block;text-transform:capitalize!important}.firstDiv{word-break:break-word;overflow-wrap:break-word;white-space:normal}.container{display:flex;flex-wrap:wrap;margin:20px;gap:20px;background-color:#fff;padding:20px;border-radius:10px}.item{width:calc(33.33% - 20px);background-color:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 5px #0000001a}.forCommentImg{width:70px;border-radius:16px;margin:8px 0;cursor:pointer}.image-modal img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 4px 10px #00000080}.full-image-modal{position:fixed;background:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.full-image-modal .full-image{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 10px #fff3}.item-content{font-size:14px;line-height:1.5;max-height:220px;overflow-y:auto}.image-modal.full-image-modal{position:fixed;width:100vw;height:100vh;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:9999;overflow:hidden;cursor:zoom-out}.image-modal.full-image-modal img{border-radius:8px;box-shadow:0 4px 20px #0006;object-fit:contain;transition:transform .3s ease}.image-modal.full-image-modal img:hover{transform:scale(1.02)}::ng-deep .custom-overlay-wrapper .custom-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:9999}::ng-deep .custom-overlay-wrapper .custom-modal{background:#fff;border-radius:12px;box-shadow:0 8px 25px #0003;width:360px;max-width:90%;padding:24px;text-align:center;animation:fadeInScale .25s ease}::ng-deep .custom-overlay-wrapper .custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}::ng-deep .custom-overlay-wrapper .modal-actions{display:flex;justify-content:center;gap:12px}::ng-deep .custom-overlay-wrapper .modal-actions button{min-width:90px;padding:8px 14px;border-radius:6px;border:none;font-weight:500;cursor:pointer;transition:background-color .2s ease}::ng-deep .custom-overlay-wrapper .btn-confirm{background-color:#007bff;color:#fff}::ng-deep .custom-overlay-wrapper .btn-confirm:hover{background-color:#0069d9}::ng-deep .custom-overlay-wrapper .btn-cancel{background-color:#e4e4e4;color:#333}::ng-deep .custom-overlay-wrapper .btn-cancel:hover{background-color:#d6d6d6}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.clear-btn{background:linear-gradient(135deg,#f53545,#f53545);border:none;color:#fff;font-size:13px;padding:3px 6px;border-radius:20px;font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px #ff5f6d66;position:relative;bottom:4px}.clear-btn:hover{transform:translateY(-2px);box-shadow:0 4px 10px #ff5f6d99;background:linear-gradient(135deg,#f53545,#f53545)}.clear-btn i{font-size:16px;vertical-align:middle}.cell-editin-dropdown .deopdown-item{width:100%!important;box-shadow:none!important;border-radius:4px;cursor:pointer;padding-block:8px!important}.cell-editin-dropdown .deopdown-item:hover{background-color:#f1f1f1}\n"] }]
6187
+ ], template: "<div class=\"position-relative h-100\">\r\n <div\r\n class=\"d-flex justify-content-between mb-2 align-items-center position-relative\"\r\n >\r\n <div class=\"d-flex gap-2\">\r\n <div class=\"nav nav-tabs\" *ngIf=\"true\">\r\n <div class=\"nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\r\n <span\r\n *ngFor=\"let tab of tabs; let i = index\"\r\n (click)=\"setActiveTab(tab)\"\r\n class=\"nav-link cursor-pointer\"\r\n [class.active]=\"activeTab == tab\"\r\n >\r\n {{ tab }}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"global-search\" [style.width.px]=\"350\">\r\n <span\r\n *ngIf=\"enableGlobalSearch\"\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 *ngIf=\"enableGlobalSearch\"\r\n style=\"height: 36px\"\r\n class=\"form-control\"\r\n placeholder=\"Type to search, then press Enter\"\r\n [(ngModel)]=\"tableSearch\"\r\n (keydown.enter)=\"onGlobalSearch()\"\r\n (input)=\"onSearchInput($event)\"\r\n type=\"search\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex gap-2 align-items-center table-right-top-actions\">\r\n <ng-container *ngFor=\"let button of buttons\">\r\n <div\r\n class=\"d-flex align-items-center gap-2 action-buttons-row\"\r\n *ngIf=\"button?.has_permission\"\r\n >\r\n <a\r\n href=\"JavaScript:void(0)\"\r\n (click)=\"onActionButtonClick(button.name)\"\r\n class=\"button button-small btn border border-primary btn-active-primary me-2 p-0 d-flex align-items-center justify-content-center px-3\"\r\n >\r\n <span\r\n *ngIf=\"button.is_showIcon\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/' + button.icon + '.svg'\r\n \"\r\n class=\"svg-icon svg-icon-2\"\r\n ></span>\r\n <span\r\n class=\"label-hidden text-white\"\r\n [class.ms-0]=\"button.is_showIcon\"\r\n >{{ button?.name }}</span\r\n >\r\n </a>\r\n </div>\r\n </ng-container>\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\r\n <div class=\"action-buttons-row\" *ngIf=\"showFullScreenButton\">\r\n <a\r\n *ngIf=\"!isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Minimise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/expend.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\r\n <a\r\n *ngIf=\"isFullScreen\"\r\n class=\"button button-small btn btn-active-primary border border-primary expend d-flex justify-content-center align-items-center\"\r\n (click)=\"toggleFullscreen()\"\r\n data-bs-toggle=\"tooltip\"\r\n data-bs-placement=\"top\"\r\n title=\"Maximise\"\r\n [ngClass]=\"{ minArrow: !isFullScreen, maxArrow: isFullScreen }\"\r\n style=\"transition: color 0.2s\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/minimize.svg'\"\r\n class=\"svg-icon svg-icon-2 mb-1\"\r\n ></span>\r\n </a>\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>\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 [style.backgroundColor]=\"bodyBackgroundColor\"\r\n id=\"data-grid-main-container\"\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\r\n class=\"d-flex gap-2 align-items-center\"\r\n [style.color]=\"headerTextColor\"\r\n >\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 <div\r\n cdkDropListOrientation=\"horizontal\"\r\n cdkDropList\r\n (cdkDropListDropped)=\"onGroupReorder($event)\"\r\n class=\"d-flex\"\r\n >\r\n <div\r\n cdkDrag\r\n [cdkDragLockAxis]=\"'x'\"\r\n *ngFor=\"\r\n let child of groupedColumns;\r\n let i = index;\r\n trackBy: trackByField\r\n \"\r\n class=\"d-flex align-items-center\"\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-template cdkDragPreview\r\n ><div class=\"p-2 border d-flex gap-2\">\r\n <div>\r\n <span\r\n *ngIf=\"!draggingInGroupArea\"\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>{{ child.header }}</div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\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\r\n class=\"data-grid-header left-pinned\"\r\n #leftPinnedHeader\r\n [class.border-right]=\"hasLeftPinnedColumns\"\r\n >\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]=\"55\"\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\r\n </div>\r\n <div\r\n *ngIf=\"showCheckboxes\"\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 style=\"width: 16px; height: 16px\"\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 [style.backgroundColor]=\"headerBackgroundColor\"\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: 1px\"\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 *ngIf=\"!draggingInGroupArea\"\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)=\"onCenterBodyScroll($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)=\"\r\n openThreeDotsMenu($event, 'group');\r\n isThreeDotsFilterOpen = false\r\n \"\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)=\"\r\n $event.stopPropagation(); onResizeGroupBox($event)\r\n \"\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 === 'Assets' || gridType === 'Tasks'\"\r\n >\r\n </span>\r\n <div\r\n class=\"dragable-header\"\r\n (cdkDragStarted)=\"\r\n checkColumnGroupingStatus(col);\r\n dragStartOnGroup(col);\r\n onDragStarted(col)\r\n \"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\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 *ngIf=\"!isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (draggingInGroupArea\r\n ? 'data-grid/icons/justify.svg'\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 >\r\n </span>\r\n <span\r\n *ngIf=\"isOutsideContainer\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/eye-cross.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n >\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 && !isOutsideContainer\"\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>\r\n\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <!-- Data Grid Right Pinned Header starts here -->\r\n <!-- ********************************************************************************* -->\r\n <!-- ********************************************************************************* -->\r\n <div\r\n [style.backgroundColor]=\"headerBackgroundColor\"\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: 'right'\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 *ngIf=\"!draggingInGroupArea\"\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: 'right'\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 && !dataSetLoading\"\r\n >\r\n <!-- <div\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/record-not-found.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></div> -->\r\n <div>No Record Found</div>\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 || dataSetLoading\"\r\n style=\"\r\n z-index: 999;\r\n backdrop-filter: blur(1px);\r\n \"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div class=\"spinner-border text-primary\" role=\"status\">\r\n <!-- <span class=\"loader\"></span> -->\r\n <!-- <span class=\"visually-hidden\">Loading...</span> -->\r\n <!-- </div> -->\r\n </div>\r\n </div>\r\n\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 [style.scrollbarWidth]=\"verticalScrollbarWidth\"\r\n >\r\n <!-- LEFT PINNED -->\r\n <div\r\n [style.height.px]=\"\r\n !groupedColumns.length ? originalDataSet.length * rowHeight : 0\r\n \"\r\n ></div>\r\n <div [class.h-100]=\"originalDataSet.length < 8\">\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]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"leftPinnedBackgroundColor\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n\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 isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewLeftPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'left',\r\n isTotalRow: true\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=\"h-100\"\r\n [style.width.px]=\"centerPinnedHeader.clientWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body center-scrollable\"\r\n [class.h-100]=\"originalDataSet.length < 8\"\r\n style=\"overflow-y: hidden; overflow-x: auto\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n #centerScrollableBody\r\n (scroll)=\"onCenterBodyScroll($event)\"\r\n [style.boxShadow]=\"leftPinnedBoxshadow\"\r\n >\r\n <div [@rowDynamic]=\"rowAnimation\" *ngIf=\"!loading && !dataSetLoading\">\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 isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewCenterColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'center',\r\n isTotalRow: true\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 < 8\"\r\n [style.maxWidth.px]=\"\r\n isScrollbarVisible\r\n ? rightPinnedHeader.offsetWidth - 15\r\n : rightPinnedHeader.offsetWidth\r\n \"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n >\r\n <div\r\n class=\"data-grid-body right-pinned-body w-100 h-100\"\r\n style=\"overflow-y: hidden\"\r\n [style.transform]=\"'translateY(' + translateY + 'px)'\"\r\n [style.boxShadow]=\"rightPinnedBoxshadow\"\r\n [style.backgroundColor]=\"rightPinnedBackgroundColor\"\r\n *ngIf=\"!loading && !dataSetLoading\"\r\n [@rowDynamic]=\"rowAnimation\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let row of visibleRows;\r\n let i = index;\r\n trackBy: trackById\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: row,\r\n columns: previewRightPinnedColumns,\r\n isEven: (startIndex + i) % 2 === 0,\r\n isOdd: (startIndex + i) % 2 !== 0,\r\n section: 'right',\r\n isTotalRow: false\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"showTotalAmountRow && originalDataSet?.length\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n rowCell;\r\n context: {\r\n $implicit: { __virtualIndex: 0 },\r\n columns: previewRightPinnedColumns,\r\n isEven: false,\r\n isOdd: false,\r\n section: 'right',\r\n isTotalRow: true\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n style=\"top: auto; left: auto\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n fullscreenImage = null;\r\n cdr.detectChanges()\r\n \"\r\n [style.width.px]=\"dataGridContainer.offsetWidth\"\r\n [style.height.px]=\"\r\n dataGridContainer.offsetHeight - (footerRowHeight + 100)\r\n \"\r\n class=\"image-modal full-image-modal\"\r\n *ngIf=\"fullscreenImage\"\r\n >\r\n <img\r\n (click)=\"$event.stopPropagation()\"\r\n [src]=\"fullscreenImage\"\r\n alt=\"Fullscreen Image\"\r\n />\r\n </div>\r\n <div\r\n *ngIf=\"selectedRows.size > 0 && showTaskbar\"\r\n class=\"taskbar w-100\"\r\n [style.bottom.px]=\"85\"\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 {{\r\n paginationConfig.totalResults ||\r\n config?.paginationParams?.totalItems\r\n }}\r\n Total\r\n </span>\r\n <div class=\"action-buttons d-flex align-items-center\">\r\n <ng-container\r\n *ngFor=\"let action of taskbarActions; let i = index\"\r\n >\r\n <ng-container *ngIf=\"action?.has_permission\">\r\n <span\r\n class=\"action-btn verified btn {{ action }}\"\r\n (click)=\"onVerifyClick(action?.actionName)\"\r\n >{{ action?.actionName }}</span\r\n >\r\n <span\r\n *ngIf=\"\r\n taskbarActions.length > 1 &&\r\n i !== taskbarActions.length - 1 &&\r\n taskbarActions[i + 1]?.has_permission\r\n \"\r\n class=\"\"\r\n >|</span\r\n >\r\n </ng-container>\r\n </ng-container>\r\n <button (click)=\"clearSelectionState(tableType);selectedRows.clear();\" class=\"clear-btn ms-2 mt-2\">\r\n <i class=\"bi bi-x-circle\"></i> Clear Selection\r\n </button>\r\n </div>\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 * dataSetLength\"></div>\r\n </div> -->\r\n </div>\r\n\r\n <!-- Horizintal Fake Scrollbars -->\r\n <div\r\n class=\"d-flex justify-content-between\"\r\n *ngIf=\"hasScroll\"\r\n >\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)=\"onCenterBodyScroll($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 - 10\"></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\"\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-fff]=\"\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-fff]=\"\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\r\n [style.height.px]=\"footerRowHeight\"\r\n class=\"border-top\"\r\n [style.backgroundColor]=\"footerRowBackgroundColor\"\r\n >\r\n <!-- Rows: <span class=\"fw-500 ms-1\">{{ dataSet.length }}</span> -->\r\n\r\n <div\r\n class=\"pagination-container\"\r\n [style.height.px]=\"footerRowHeight\"\r\n [style.padding.px]=\"footerPadding\"\r\n >\r\n <div class=\"page-size\">\r\n <select\r\n [(ngModel)]=\"paginationConfig.limit\"\r\n (change)=\"onPageSizeChange()\"\r\n >\r\n <option *ngFor=\"let size of pageSizeOptions\" [value]=\"size\">\r\n {{ size }}\r\n </option>\r\n </select>\r\n <span class=\"separator\"> per page </span>\r\n </div>\r\n\r\n <div class=\"page-info\">\r\n Results:\r\n {{ (paginationConfig.page - 1) * paginationConfig.limit + 1 }}-{{\r\n paginationConfig.page * paginationConfig.limit <\r\n paginationConfig.totalResults\r\n ? paginationConfig.page * paginationConfig.limit\r\n : paginationConfig.totalResults\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)=\"\r\n $event.stopPropagation(); onResizeGroup($event, col, pinnedRight)\r\n \"\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 align-items-center 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)=\"\r\n openThreeDotsMenu($event, child);\r\n openFilteronThreeDotsClick(child)\r\n \"\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)=\"\r\n openThreeDotsMenu($event, child);\r\n isThreeDotsFilterOpen = false\r\n \"\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 [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: child,\r\n isNestedTable: false,\r\n section: sections\r\n }\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)=\"\r\n $event.stopPropagation();\r\n onResizeColumn($event, child)\r\n \"\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)]=\"child.filterValue\"\r\n (ngModelChange)=\"onFilterChange(child)\"\r\n (paste)=\"onFilterChange(child); applyDropdownFilter()\"\r\n [readonly]=\"\r\n child?.type == 'dropdown' || child?.type == 'image'\r\n \"\r\n [class.disabled-search-input]=\"\r\n child?.type == 'dropdown' || child?.type == 'image'\r\n \"\r\n (click)=\"\r\n $event.stopPropagation();\r\n openFilterFromDisabledSearchedInput(child)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\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 [class.pe-none]=\"child?.type == 'image'\"\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\r\n class=\"group-column-wrapper\"\r\n *ngIf=\"col.is_visible && !col['isRowGrouped']\"\r\n >\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 align-items-center\"\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)=\"\r\n openThreeDotsMenu($event, col);\r\n openFilteronThreeDotsClick(col)\r\n \"\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 <!-- Ascending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'asc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + '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 cursor-pointer\"\r\n (click)=\"sortDesc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'asc'\"\r\n ></span>\r\n\r\n <!-- Descending Sort Icon -->\r\n <span\r\n *ngIf=\"sortingConfig?.order_by == 'desc'\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/sort-desc.svg'\r\n \"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center mt-1 cursor-pointer\"\r\n (click)=\"sortAsc(col)\"\r\n [class.active]=\"sortingConfig?.order_by === 'desc'\"\r\n ></span>\r\n </div>\r\n <div\r\n class=\"three-dots p-1\"\r\n (click)=\"\r\n openThreeDotsMenu($event, col);\r\n isThreeDotsFilterOpen = false\r\n \"\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 [style.top.px]=\"\r\n isThreeDotsFilterOpen\r\n ? showFilterRow || showColumnsGrouping\r\n ? headerRowHeight * 2 - 10\r\n : headerRowHeight - 10\r\n : 0\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: false,\r\n section: sections\r\n }\r\n \"\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)=\"\r\n $event.stopPropagation(); onResizeColumn($event, col)\r\n \"\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 [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image'\r\n \"\r\n (paste)=\"onPasteInFilterRowSearch($event, col)\"\r\n (click)=\"\r\n $event.stopPropagation(); openFilterFromDisabledSearchedInput(col)\r\n \"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n (mousedown)=\"$event.stopPropagation()\"\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 [class.pe-none]=\"col?.type == 'image'\"\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 let-isTotalRow=\"isTotalRow\"\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 d-flex align-items-center\"\r\n [style.height.px]=\"rowHeight\"\r\n [class.border-below]=\"section !== 'center'\"\r\n [style.width]=\"\r\n section === 'center'\r\n ? (centerScrollableBody?.scrollWidth ?? 0) + '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]=\"55\"\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 [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) || \"\" }}\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 [style.color]=\"checkboxesColor\"\r\n >\r\n <input\r\n style=\"width: 16px; height: 16px\"\r\n type=\"checkbox\"\r\n [checked]=\"getGroupCheckedState(row) === true\"\r\n [indeterminate]=\"getGroupCheckedState(row) === undefined\"\r\n (change)=\"selectGroupRow($event, row)\"\r\n />\r\n\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 [style.minWidth.px]=\"centerPinnedHeader.scrollWidth\"\r\n class=\"d-flex align-items-center ps-2 h-100 border-below\"\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 * 30 : 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 align-items-center d-flex\"\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\" [@slideToggle]>\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 isTotalRow: isTotalRow\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\r\n class=\"d-flex\"\r\n [style.height.px]=\"rowHeight\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\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=\"\r\n section == 'center' && (gridType === 'Assets' || gridType === 'Tasks')\r\n \"\r\n [ngStyle]=\"{\r\n 'background-color': rowSelectedIndexes.has(row.__virtualIndex)\r\n ? null\r\n : getBackgroundColor(row, isEven, section)\r\n }\"\r\n [class.selected-cell]=\"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 <span\r\n (click)=\"toggleDetailRowExpand(row)\"\r\n *ngIf=\"row?.detail?.result?.length || gridType === 'Tasks'\"\r\n class=\"data-grid-svg-icon filter-icon-wrapper\"\r\n [inlineSVG]=\"\r\n isDetailsExpanded(row)\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)\"\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': getBackgroundColor(row, isEven, section)\r\n }\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n ></div>\r\n <div\r\n (contextmenu)=\"onRightClick($event, row)\"\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': getBackgroundColor(row, isEven, section)\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]=\"55\"\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 [style.color]=\"checkboxesColor\"\r\n >\r\n {{ getStartIndex() + (row.__virtualIndex - 1) }}\r\n </div>\r\n <div\r\n class=\"border-below\"\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 && showCheckboxes\"\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 [style.minHeight.px]=\"rowHeight - 1\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n >\r\n <input\r\n *ngIf=\"hasAnyVisibleColumn\"\r\n style=\"width: 16px; height: 16px\"\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 isTotalRow: isTotalRow\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 *ngIf=\"col?.is_visible && !col?.isRowGrouped\">\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 isTotalRow: isTotalRow\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'left' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'center' && isDetailsExpanded(row)\"\r\n class=\"accordion-details center-section\"\r\n style=\"\r\n max-height: 350px;\r\n overflow-y: hidden;\r\n overflow-x: auto;\r\n scrollbar-width: thin;\r\n \"\r\n #nestedTable\r\n [style.width]=\"\r\n hasRightPinnedColumns\r\n ? '100%'\r\n : hasVerticalScroll\r\n ? 'calc(100% - 12px)'\r\n : '100%'\r\n \"\r\n >\r\n <ng-container *ngIf=\"gridType == 'Assets'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"nestedTableTemplate; context: { $implicit: row }\"\r\n ></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"gridType == 'Tasks'\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n taskManagementTemplate;\r\n context: { taskDetails: row }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n <div\r\n [@slideToggle]\r\n *ngIf=\"section === 'right' && isDetailsExpanded(row)\"\r\n class=\"accordion-details\"\r\n style=\"max-height: 350px; overflow: hidden\"\r\n [style.maxHeight.px]=\"hasHorizontalScroll ? 339 : 341\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n leftRightNestedPlaceholder;\r\n context: { $implicit: row }\r\n \"\r\n >\r\n </ng-container>\r\n </div>\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 let-isTotalRow=\"isTotalRow\"\r\n>\r\n <div\r\n #cellContainer\r\n (click)=\"\r\n editingKey = ''; setActiveCell(row, col); collapseAllExpandedCells()\r\n \"\r\n [style.fontWeight]=\"bodyFontWeight\"\r\n [class.border-right]=\"showVerticalBorder\"\r\n class=\"cell overflow-visible position-relative data-grid-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.fontSize.px]=\"bodyTextFontsSize\"\r\n [style.minHeight.px]=\"rowHeight\"\r\n [style.maxHeight.px]=\"rowHeight\"\r\n [class.active-cell]=\"\r\n isActiveCell(row, col) && !isEditing(row, col) && selectedKeys.size == 1\r\n \"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, false, cellContainer)\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 tabindex=\"-1\"\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\r\n class=\"table-cell\"\r\n [class.active-for-editing]=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n getNestedValue(row, col.field)?.length <= 50)\r\n \"\r\n >\r\n <div\r\n (click)=\"$event.stopPropagation()\"\r\n *ngIf=\"\r\n isEditing(row, col) &&\r\n (getNestedValue(row, col.field)?.length === undefined ||\r\n (getNestedValue(row, col.field)?.length <= 50 &&\r\n !expandedCells.size));\r\n else viewMode\r\n \"\r\n >\r\n\r\n <ng-container *ngIf=\"col.cellEditor; else builtInEditors\">\r\n <ng-container\r\n [cellEditor]=\"col.cellEditor\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col.field)\"\r\n (editorEvent)=\"finishEdit($event)\"\r\n ></ng-container>\r\n </ng-container>\r\n\r\n <ng-template #builtInEditors>\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 editing-dropdown-search-input\" *ngIf=\"col?.column_dropdown_value?.length > 5\">\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 (mousedown)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n <cdk-virtual-scroll-viewport \r\n itemSize=\"35\" \r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n [class.selected]=\"getNestedValue(row, col.field) == option?.value || getNestedValue(row, col.field) == option\"\r\n class=\"px-2 py-1 d-flex align-items-center dropdown-item\"\r\n *cdkVirtualFor=\"\r\n let option of col.column_dropdown_value \r\n | filter : editinDropdownSearch : 'value'\r\n \"\r\n (click)=\"setNestedValue(row, col, option, true); editingKey = null\"\r\n >\r\n <label\r\n \r\n class=\"form-check-label d-flex align-items-center mb-0 cursor-pointer\"\r\n [for]=\"col.field + '-' + (option.value || option)\"\r\n >\r\n {{ option.value || option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n\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 </ng-template>\r\n\r\n </div>\r\n\r\n <!-- Display mode -->\r\n <ng-template #viewMode>\r\n <div\r\n class=\"d-flex justify-content-between align-items-center w-100 overflow-hidden\"\r\n [ngClass]=\"getCellClasses(col, getNestedValue(row, col.field))\"\r\n >\r\n <!-- Field icon (for Tasks grid) -->\r\n <ng-container\r\n *ngIf=\"gridType === 'Tasks' && iconMap[col.field] && !isTotalRow\"\r\n >\r\n <span\r\n class=\"cursor-pointer me-2\"\r\n (click)=\"$event.preventDefault(); $event.stopPropagation()\"\r\n [inlineSVG]=\"iconMap[col.field](row, col)\"\r\n ></span>\r\n </ng-container>\r\n\r\n <!-- \u2705 Custom cell renderer support -->\r\n <ng-container *ngIf=\"col.cellRenderer; else defaultCell\">\r\n <ng-container\r\n [cellRenderInit]=\"col.cellRenderer\"\r\n [rowData]=\"row\"\r\n [colData]=\"col\"\r\n [cellValue]=\"getNestedValue(row, col?.field)\"\r\n (cellEvent)=\"onCellEvent($event)\"\r\n >\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- \uD83E\uDDFE Default text-based cell rendering -->\r\n <ng-template #defaultCell>\r\n <div\r\n #cellText\r\n class=\"text-ellipsis flex-grow-1\"\r\n [title]=\"getCellTitle(row, col)\"\r\n >\r\n <!-- Normal cell -->\r\n <ng-container\r\n *ngIf=\"\r\n col.type !== 'image' &&\r\n col.field != 'image' &&\r\n col.field != 'invoice.invoice_image' &&\r\n !isTotalRow\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{getCellTitle(row, col)}}\r\n </ng-container>\r\n\r\n <!-- Total row -->\r\n <ng-container *ngIf=\"isTotalRow\">\r\n {{ getTotalAmount(col) }}\r\n </ng-container>\r\n\r\n <!-- Invoice Image -->\r\n <ng-container *ngIf=\"col.field == 'invoice.invoice_image'\">\r\n <div style=\"display: flex; align-items: center; zoom: 0.7\">\r\n <span\r\n title=\"{{ getNestedValue(row, col.field) || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(getNestedValue(row, col.field))\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(getNestedValue(row, col.field)) +\r\n '.svg'\r\n \"\r\n ></span>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Image cell -->\r\n <ng-container *ngIf=\"col.type == 'image' && !isTotalRow\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n defaultImagePlaceholder;\r\n context: { row: row, col: col }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n <span\r\n *ngIf=\"\r\n (!col?.cellRenderer && showCellDetailsBox &&\r\n getNestedValue(row, col.field)?.length > 50 && col.type !== 'image') ||\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 </ng-template>\r\n <!-- Expand / Collapse icon -->\r\n </div>\r\n\r\n <!-- Expanded text -->\r\n <div\r\n class=\"position-absolute w-100 expanded-box\"\r\n *ngIf=\"isExpanded(row, col)\"\r\n [style.zIndex]=\"getZIndex(row, col)\"\r\n style=\"top: 100%; left: 0\"\r\n [attr.id]=\"(row.id || row._id) + '-' + (col.id || col._id)\"\r\n [class.invisible]=\"!showDetailsBox\"\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 </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Headers Action List On clicking three dots -->\r\n\r\n<ng-template\r\n #columnMenu\r\n let-col=\"col\"\r\n let-isNestedTable=\"isNestedTable\"\r\n let-columns=\"columns\"\r\n let-section=\"section\"\r\n>\r\n <div\r\n class=\"column-menu three-dots-col-menu\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n *ngIf=\"activeCol && !isThreeDotsFilterOpen\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n [style.color]=\"headerTextColor\"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'left',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n 'right',\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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)=\"\r\n $event.stopPropagation();\r\n updateColumnPinInSourceByField(\r\n activeCol,\r\n null,\r\n isNestedTable,\r\n columns\r\n )\r\n \"\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 [class.disable-sorting]=\"!col.is_groupable\"\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\r\n @slideToggle\r\n *ngIf=\"isThreeDotsFilterOpen\"\r\n class=\"three-dots-col-menu position-relative\"\r\n [style.right.px]=\"section == 'right' ? null : col.width - 45\"\r\n [class.visually-hidden]=\"isMenueHidden\"\r\n >\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<!-- 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 class=\"form-control form-control-sm\"\r\n placeholder=\"Search...\"\r\n type=\"search\"\r\n [(ngModel)]=\"addFilterColumnInput\"\r\n />\r\n\r\n <div class=\"form-check mb-1 mt-2 ps-4 ms-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 ps-1\">\r\n <div\r\n class=\"form-check mb-1\"\r\n *ngFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById;\r\n let i = index\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </div> -->\r\n <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"filter-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of selectedColumnForFilter?.column_dropdown_value\r\n | filter : addFilterColumnInput : 'value';\r\n trackBy: trackById\r\n \"\r\n >\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"option?.id ?? option?._id ?? option\"\r\n [checked]=\"\r\n currentFilterSelectedIds.has(option?.id ?? option?._id ?? option)\r\n \"\r\n (change)=\"toggleSelectionInFilter(option)\"\r\n />\r\n\r\n <label\r\n class=\"form-check-label fw-semibold\"\r\n [for]=\"option?.id ?? option?._id ?? option\"\r\n >\r\n {{ option?.value ?? option?.name ?? option }}\r\n </label>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\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 custom-select\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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)]=\"firstValue\"\r\n #filterMenueTextchInput\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n\r\n <div class=\"form-group mb-3 d-flex flex-row\">\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1 gap-1\"\r\n >\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 (change)=\"cdr.detectChanges()\"\r\n />\r\n <label class=\"form-check-label mb-0 mt-1\" for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <div @slideToggle *ngIf=\"firstValue && condition != 'none'\">\r\n <div class=\"form-group mb-2\">\r\n <select\r\n class=\"form-select form-select-sm custom-select\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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=\"Second Value\"\r\n [(ngModel)]=\"secondValue\"\r\n />\r\n </div>\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: 30px\"\r\n (click)=\"applyDropdownFilter()\"\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: 30px\"\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<!-- 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 d-none\"\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 mt-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\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\" *ngIf=\"showColumnsGrouping\">\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 <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% - 70px); 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 </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\r\n class=\"column-group d-flex align-items-center mb-2\"\r\n *ngIf=\"col.type !== 'image'\"\r\n >\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\" *ngIf=\"col.type !== 'image'\">\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)]=\"sideNestedFilterSearch\"\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 : sideNestedFilterSearch : 'value'\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 <cdk-virtual-scroll-viewport\r\n itemSize=\"32\"\r\n class=\"dropdown-viewport\"\r\n style=\"height: 120px\"\r\n >\r\n <div\r\n class=\"form-check mb-1 ms-1\"\r\n *cdkVirtualFor=\"\r\n let option of col?.column_dropdown_value\r\n | filter : sideNestedFilterSearch : 'value'\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\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 </cdk-virtual-scroll-viewport>\r\n\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)=\"applySideFilter(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\" \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-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\"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n\r\n <input\r\n [type]=\"col.type == 'date' ? 'date' : 'text'\"\r\n class=\"form-control form-control-sm mb-3\"\r\n placeholder=\"Value\"\r\n [(ngModel)]=\"col!.query!.first_value\"\r\n />\r\n\r\n <div\r\n class=\"form-group mb-3 d-flex flex-row muted\"\r\n style=\"font-size: 14px\"\r\n >\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"and_{{ col.field }}\"\r\n >AND</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"or_{{ col.field }}\"\r\n >OR</label\r\n >\r\n </div>\r\n <div\r\n class=\"form-check form-check-inline m-0 col-4 d-flex align-items-center gap-1\"\r\n >\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\r\n class=\"nnonem-check-label mb-0 mt-1\"\r\n for=\"none_{{ col.field }}\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n <ng-container\r\n *ngIf=\"col?.query?.first_value && col?.query?.condition !== 'none'\"\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\"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"col.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </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=\"Second Value\"\r\n [(ngModel)]=\"col!.query.second_value\"\r\n />\r\n </ng-container>\r\n <!-- <div class=\"d-flex gap-2\">\r\n <div class=\"btn btn-sm btn-primary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">apply</div>\r\n <div class=\"btn btn-sm btn-secondary d-flex justify-content-center align-items-center\" style=\"height: 22px;\" (click)=\"applyDropdownFilter()\">reset</div>\r\n\r\n </div> -->\r\n </div>\r\n </ng-template>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\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(); removeSideFilter(col)\"\r\n >\r\n <span>Clear</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"max-height: 30px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applySideFilter(col)\"\r\n [class.disabled]=\"(col?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n [class.pe-none]=\"(col!?.query.condition !== 'none' && !col?.query?.second_value)\"\r\n >\r\n <span style=\"margin-top: -1px\">Apply</span>\r\n </button>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Centr Overlay for showing the chose columns -->\r\n\r\n<div *ngIf=\"showColumnPanel\" class=\"custom-modal-overlay\">\r\n <div\r\n class=\"custom-modal-content\"\r\n [style.backgroundColor]=\"dropdownsBackgroundColor\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"modalColumnPannel\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- The existing ng-template you provided -->\r\n<ng-template #modalColumnPannel>\r\n <div class=\"column-panel-header\">\r\n <div\r\n class=\"d-flex justify-content-between align-items-center px-2 ps-3 rounded-top-2 moda-header\"\r\n [style.height.px]=\"48\"\r\n >\r\n Choose Columns\r\n <span class=\"filter-icon-wrapper\" (click)=\"closeModalColumnPanel()\"\r\n ><span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/x.svg'\"\r\n class=\"data-grid-svg-icon d-flex justify-content-center align-items-center\"\r\n ></span\r\n ></span>\r\n </div>\r\n <hr class=\"my-0\" />\r\n <div>\r\n <div class=\"d-flex align-items-center px-2 pe-3\" [style.height.px]=\"48\">\r\n <span class=\"filter-icon-wrapper me-2\" *ngIf=\"showColumnsGrouping\">\r\n <span\r\n class=\"toggle-icon data-grid-svg-icon\"\r\n [inlineSVG]=\"\r\n accordionState === 'all'\r\n ? singleSpaAssetsPath + 'data-grid/icons/chevron-down.svg'\r\n : accordionState === 'some'\r\n ? singleSpaAssetsPath + 'data-grid/icons/dash.svg'\r\n : singleSpaAssetsPath + 'data-grid/icons/chevron-right.svg'\r\n \"\r\n (click)=\"toggleAllAccordions()\"\r\n ></span>\r\n </span>\r\n <input\r\n type=\"checkbox\"\r\n class=\"form-check-input me-2\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <input\r\n type=\"text\"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Search columns...\"\r\n [(ngModel)]=\"choseColumnsSearch\"\r\n />\r\n </div>\r\n\r\n <hr class=\"mt-0 mb-1\" />\r\n <div class=\"px-2 overlay-scrollable\">\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : choseColumnsSearch : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"columnPanelItem; context: { col: col }\"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #sideMenuRowGroups>\r\n <div class=\"d-flex flex-column h-100 d-none\">\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 cdkDragHandle\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 [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 align-items-center 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 [readonly]=\"col?.type == 'dropdown' || col?.type == 'image'\"\r\n [class.disabled-search-input]=\"\r\n col?.type == 'dropdown' || col?.type == 'image'\r\n \"\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 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 class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Side Menu</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showSideMenu\"\r\n type=\"checkbox\"\r\n id=\"rowShading\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\r\n <span>Show Filter Row</span>\r\n <div class=\"form-check form-switch m-0\">\r\n <input\r\n class=\"form-check-input\"\r\n [(ngModel)]=\"showFilterRow\"\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 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 text-primary\"\r\n type=\"button\"\r\n id=\"savePresetDropdown\"\r\n (click)=\"$event.stopPropagation(); toggleSubActions('save-preset')\"\r\n >\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update 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\r\n class=\" pb-5 overflow-auto\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 250\"\r\n >\r\n <div\r\n class=\"cursor-pointer\"\r\n (click)=\"\r\n clearAllFilters();\r\n openIndex = null;\r\n temp_state.id = '';\r\n activeTopButton = '';\r\n curretaTablePresetForUpdate = null\r\n \"\r\n >\r\n <div class=\"fw-semibold\">Default View</div>\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n <small class=\"text-dark\">Created by system</small>\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n class=\"badge bg-light text-primary ms-2\"\r\n >Default</span\r\n >\r\n <span\r\n *ngIf=\"!tableFilterViewId && !hasAnyDefaultView()\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/check-blue.svg'\"\r\n class=\"me-2\"\r\n ></span>\r\n <div\r\n class=\"dropdown d-flex justify-content-end\"\r\n *ngIf=\"tableFilterViewId\"\r\n ></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=\"\r\n let table of filteredList;\r\n let i = index;\r\n trackBy: trackByTable\r\n \"\r\n >\r\n <!-- Item -->\r\n <div\r\n (click)=\"\r\n $event.stopPropagation(); openIndex = null; activeTopButton = ''\r\n \"\r\n class=\"list-group-item px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div (click)=\"selectFilter(table); openIndex = null\">\r\n <div class=\"fw-semibold\" style=\"cursor: pointer\">\r\n {{ table?.name }}\r\n <!-- {{table?.is_temp}} -->\r\n <span\r\n *ngIf=\"\r\n (table?.is_temp && !temp_state.id) ||\r\n temp_state.id == table.id\r\n \"\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_default\"\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\" *ngIf=\"table?.config?.filterNames\" [title]=\"table?.config?.filterNames\">\r\n {{\r\n table?.config?.filterNames?.length > 25 \r\n ? (table?.config?.filterNames | slice:0:25) + '...'\r\n : table?.config?.filterNames\r\n }}\r\n ({{ table?.config?.totalCount }})\r\n </small>\r\n <small class=\"text-dark\" *ngIf=\"!table?.config?.filterNames\">{{ table?.createdAt | date : \"MMM d, y\" }}</small>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <span\r\n *ngIf=\"table?.is_default\"\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_default\">\r\n <div\r\n class=\"dropdown-wrapper\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"btn-icon muted-text\"\r\n (click)=\"toggleMenu(i, $event)\"\r\n aria-haspopup=\"true\"\r\n [attr.aria-expanded]=\"openIndex === i\"\r\n >\r\n <span\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/horizontal-dots.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </button>\r\n\r\n <!-- menu -->\r\n <ul\r\n *ngIf=\"openIndex === i\"\r\n class=\"custom-dropdown-menu\"\r\n role=\"menu\"\r\n >\r\n <li role=\"none\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item\"\r\n (click)=\"\r\n actionPreset(table, 'setPreset'); temp_state.id = ''\r\n \"\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 </button>\r\n </li>\r\n\r\n <li role=\"none\" *ngIf=\"!table.confirmDelete\">\r\n <button\r\n role=\"menuitem\"\r\n class=\"dropdown-item text-danger\"\r\n (click)=\"table.confirmDelete = true\"\r\n >\r\n <span\r\n style=\"margin-top: -4px\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/icons/trash-red.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n Delete\r\n </button>\r\n </li>\r\n\r\n <li\r\n role=\"none\"\r\n *ngIf=\"table.confirmDelete\"\r\n class=\"confirm-block\"\r\n >\r\n <div class=\"px-3 py-2 text-center\">\r\n <div class=\"mb-2\">\r\n Are you sure you want to delete <br /><b\r\n >\u201C{{ table?.name }}\u201D</b\r\n >?\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-sm btn-light me-2\"\r\n (click)=\"table.confirmDelete = false\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"btn btn-sm btn-danger\"\r\n (click)=\"actionPreset(table, 'deletePreset')\"\r\n >\r\n Delete\r\n </button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Item End Here -->\r\n </div>\r\n </div>\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\">\r\n {{ isTablePresetNotChanged ? \"Save preset\" : \"Update Preset\" }}\r\n </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\" *ngIf=\"isTablePresetNotChanged\">\r\n <ng-container *ngIf=\"!closeDropdown.preset.loading\"\r\n >Save</ng-container\r\n >\r\n <ng-container *ngIf=\"closeDropdown.preset.loading\"\r\n ><span class=\"spinner-border spinner-border-sm\"></span\r\n ></ng-container>\r\n </span>\r\n <span style=\"white-space: nowrap\" *ngIf=\"!isTablePresetNotChanged\"\r\n >Update Preset</span\r\n >\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 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 d-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=\"overflow: auto; scrollbar-width: thin\"\r\n [style.maxHeight.px]=\"dataGridContainer.offsetHeight - 220\"\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 class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"hide_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"hide_all\">\r\n Show/Hide All \r\n </label>\r\n </div>\r\n </div>\r\n <!-- Item -->\r\n <ng-container\r\n *ngFor=\"\r\n let col of columns | filter : topShowHideColumns : 'header';\r\n trackBy: trackByField\r\n \"\r\n >\r\n <div\r\n *ngIf=\"col.is_visible\"\r\n class=\"list-group-item border-0 px-0 d-flex justify-content-between align-items-center\"\r\n >\r\n <div class=\"d-flex gap-1\">\r\n <div>\r\n <span\r\n *ngIf=\"!col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/grip-vertical.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n <span\r\n *ngIf=\"col?.pinned\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/pin-blue.svg'\r\n \"\r\n class=\"cursor-grap data-grid-svg-icon\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n ></span>\r\n </div>\r\n <div class=\"fw-semibold\">\r\n {{ col.header }}\r\n </div>\r\n </div>\r\n <div\r\n *ngIf=\"!col?.query?.first_value && !col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center cursor-pointer\"\r\n (click)=\"toggleColumnVisibility(col, false)\"\r\n [class.disabled]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.pe-none]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n [class.opacity-50]=\"visibleColumns().length <= 2 || col?.is_always_visible\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n <div\r\n *ngIf=\"col?.query?.first_value || col?.query?._ids?.length\"\r\n class=\"d-flex align-items-center\"\r\n style=\"opacity: 0.5\"\r\n >\r\n <span\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/eye.svg'\"\r\n class=\"data-grid-svg-icon me-2\"\r\n ></span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Item End Here -->\r\n\r\n <div\r\n class=\"dropdown-divider\"\r\n *ngIf=\"hasAnyVisibleColumn && hasAnyInVisibleColumn\"\r\n ></div>\r\n\r\n <div\r\n class=\"muted-text show-hide-table-label d-flex justify-content-between\"\r\n *ngIf=\"hasAnyInVisibleColumn\"\r\n >\r\n Hide in table\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"show_all\"\r\n [checked]=\"allColumnsSelected()\"\r\n (change)=\"toggleAllColumnsVisibility()\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" for=\"show_all\">\r\n Show/Hide All \r\n </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 actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\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 && col.type !== 'image'\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 actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 280px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\r\n >\r\n <div class=\"px-3 my-2 border-below py-1 pb-2 mb-3 d-flex ps-1\">\r\n <span\r\n (click)=\"toggleActions('filter-columns'); isActiveFilterOpen = false\"\r\n [inlineSVG]=\"singleSpaAssetsPath + 'data-grid/icons/arrow-left.svg'\"\r\n class=\"data-grid-svg-icon me-2 cursor-pointer\"\r\n ></span\r\n ><b>{{ selectedColumnForFilter?.header }}</b>\r\n </div>\r\n <div class=\"mb-2 px-3\">\r\n <div\r\n class=\"col-12 global-search position-relative border rounded d-flex align-items-center flex-wrap px-2 filter-serach-inpt\"\r\n >\r\n <span\r\n *ngFor=\"let selected of selectedFilterOptions\"\r\n class=\"badge d-flex align-items-center gap-1 me-1 mb-1\"\r\n >\r\n {{ selected?.value ? selected.value : selected }}\r\n <span\r\n (click)=\"toggleSelectionInFilter(selected)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath + 'data-grid/icons/cross-primary.svg'\r\n \"\r\n class=\"me-2\"\r\n ></span>\r\n </span>\r\n <input\r\n class=\"form-control form-control-sm border-0 flex-grow-1\"\r\n style=\"padding: 0\"\r\n [placeholder]=\"selectedFilterOptions?.length ? '' : 'Filter by'\"\r\n type=\"search\"\r\n [(ngModel)]=\"searchTextForFilterDropDown\"\r\n (keydown.backspace)=\"handleBackspace($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div\r\n class=\"list-group list-group-flush\"\r\n style=\"max-height: calc(100vh - 600px); overflow: auto\"\r\n >\r\n <ng-container\r\n *ngFor=\"\r\n let col of selectedColumnForFilter.column_dropdown_value\r\n | filter : searchTextForFilterDropDown : 'value';\r\n let i = index\r\n \"\r\n >\r\n <div\r\n class=\"list-group-item border-0 px-2 d-flex justify-content-between align-items-center dropdown-item cursor-pointer\"\r\n >\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"i\"\r\n [checked]=\"currentFilterSelectedIds.has(col.id || col._id || col)\"\r\n (change)=\"toggleSelectionInFilter(col)\"\r\n />\r\n <label class=\"form-check-label fw-semibold\" [for]=\"i\">\r\n {{ col?.value || col?.name || col }}\r\n </label>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div\r\n class=\"d-flex justify-content-center gap-2 px-2 border-top\"\r\n style=\"height: 38px\"\r\n >\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-outline-secondary btn-light border w-100 d-flex align-items-center justify-content-center mt-1 btn-light\"\r\n (click)=\"$event.stopPropagation(); resetFilterChanges()\"\r\n >\r\n <span>Cancel</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n style=\"height: 32px\"\r\n class=\"btn btn-primary w-100 d-flex align-items-center justify-content-center mt-1\"\r\n (click)=\"applyDropdownFilter()\"\r\n >\r\n <span style=\"margin-top: -2px\">Save</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For Text fields and number fields-->\r\n\r\n <div\r\n @slideToggle\r\n *ngIf=\"\r\n isFilterOpen &&\r\n (selectedColumnForFilter.type == 'string' ||\r\n selectedColumnForFilter.type == 'number' ||\r\n selectedColumnForFilter.type == 'date')\r\n \"\r\n (click)=\"$event.stopPropagation()\"\r\n class=\"shadow actions-dropdown mt-1 show shadow custom-menu table-layout filter-columns pb-2\"\r\n style=\"width: 210px; right: unset; max-width: 230px\"\r\n [style.backgroundColor]=\"checkboxesBackgroundColor\"\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 border\"\r\n [(ngModel)]=\"firstCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n <div class=\"mb-2\">\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter first value\"\r\n type=\"search\"\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n [(ngModel)]=\"firstValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n <div>\r\n <div class=\"d-flex my-3 d-flex flex-row\" style=\"font-size: 14px\">\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalAnd\"\r\n >AND</label\r\n >\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalOr\">OR</label>\r\n </div>\r\n\r\n <div\r\n class=\"form-check form-check-inline col-4 m-0 d-flex align-items-center gap-1\"\r\n >\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 mb-0 mt-1\" for=\"logicalNone\"\r\n >None</label\r\n >\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngIf=\"condition !== 'none' && firstValue\">\r\n <div class=\"mb-2 mt-3\">\r\n <!-- Second condition select -->\r\n <select\r\n class=\"form-select form-select-sm border\"\r\n [(ngModel)]=\"secondCondition\"\r\n >\r\n <ng-container *ngIf=\"selectedColumnForFilter.type !== 'date'\">\r\n <option value=\"contain\">Contains</option>\r\n <option value=\"does_not_contain\">Does Not Contain</option>\r\n <option value=\"equal\">Equals</option>\r\n <option value=\"before\">Starts With</option>\r\n <option value=\"after\">Ends With</option>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedColumnForFilter.type == 'date'\">\r\n <option value=\"equal\">Equals 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 </select>\r\n </div>\r\n\r\n <div class=\"mb-2\">\r\n <!-- Second value input -->\r\n <input\r\n [type]=\"\r\n selectedColumnForFilter.type == 'string'\r\n ? 'text'\r\n : selectedColumnForFilter.type\r\n \"\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"Enter second value\"\r\n type=\"search\"\r\n [(ngModel)]=\"secondValue\"\r\n (keydown.enter)=\"applyDropdownFilter()\"\r\n />\r\n </div>\r\n </ng-container>\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 [disabled]=\"!currentFilterSelectedIds?.size && !firstValue\"\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 [disabled]=\"(currentFilterSelectedIds?.size === 0 && !firstValue) || (condition !== 'none' && !secondValue)\"\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\">Apply</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 [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\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 [style.maxHeight.px]=\"dataGridContainer.offsetHeight / 2\"\r\n (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\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 {{\r\n item?.department_name ||\r\n item?.roleName ||\r\n item?.full_name ||\r\n \"-\"\r\n }}\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 (dblclick)=\"\r\n $event.stopPropagation();\r\n $event.preventDefault();\r\n enableEdit(row, col, true)\r\n \"\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 </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 w-100 cell-content image-placeholder\"\r\n [title]=\"row?.full_name || row?.name || 'N/A'\"\r\n >\r\n <ng-container\r\n *ngIf=\"\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice?.invoice_image ||\r\n row?.invoice_image;\r\n else placeholder\r\n \"\r\n >\r\n <span\r\n (click)=\"fullscreenImage = row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\"\r\n class=\"pic\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n <img\r\n [width]=\"rowHeight - 12\"\r\n [height]=\"rowHeight - 12\"\r\n [style.width.px]=\"rowHeight - 10\"\r\n [style.height.px]=\"rowHeight - 10\"\r\n [src]=\"\r\n row?.profile_pictures?.[4]?.path ||\r\n row?.logo ||\r\n row?.assetImage ||\r\n row?.invoice_image\r\n \"\r\n alt=\"icon\"\r\n class=\"option-icon\"\r\n loading=\"lazy\"\r\n />\r\n </span>\r\n </ng-container>\r\n <!-- <div\r\n class=\"fullscreen-overlay\"\r\n *ngIf=\"fullscreenImage\"\r\n (click)=\"fullscreenImage = null\"\r\n >\r\n <img [src]=\"fullscreenImage\" class=\"fullscreen-img\" />\r\n </div> -->\r\n\r\n <ng-template #placeholder>\r\n <span\r\n [ngClass]=\"getDynamicClass(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 [class.assets-pic]=\"gridType == 'Assets'\"\r\n >\r\n {{ getInitials(row?.full_name) }}\r\n </span>\r\n </ng-template>\r\n </span>\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 right-click-menu-icons 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\r\n<ng-template #nestedTableTemplate let-row>\r\n <div\r\n class=\"nested-table table table-sm w-100 mb-0 center-nested-table w-100\"\r\n style=\"table-layout: fixed !important\"\r\n #nestedTableContainer\r\n >\r\n <thead\r\n #nestedHeader\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n >\r\n <div\r\n cdkDropList\r\n [cdkDropListData]=\"row?.detail.columns\"\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"dropColumn($event, row)\"\r\n (cdkDropListSorted)=\"onNestedColSort($event, previewNestedCols)\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n class=\"d-flex tr border-below\"\r\n >\r\n <div\r\n *ngFor=\"let col of row.detail.columns; let i = index\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n class=\"px-4 th\"\r\n [attr.field]=\"col.field\"\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n cdkDrag\r\n >\r\n <div\r\n class=\"d-flex h-100 justify-content-between position-relative align-items-center\"\r\n >\r\n <div class=\"text-ellipsis\" (click)=\"sortNestedCol(col, row)\">\r\n {{ col.header }}\r\n </div>\r\n <div class=\"d-flex gap-2\">\r\n <span\r\n *ngIf=\"currentSubSortColumn == col.field\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n (col?.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 ms-2 start-50\"\r\n >\r\n </span>\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; left: 0\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n columnMenu;\r\n context: {\r\n col: col,\r\n isNestedTable: true,\r\n columns: row?.detail.columns\r\n }\r\n \"\r\n ></ng-container>\r\n </div>\r\n <div\r\n class=\"resize-handle\"\r\n (click)=\"$event.stopPropagation()\"\r\n (mousedown)=\"\r\n $event.preventDefault();\r\n onResizeColumn($event, col);\r\n $event.stopPropagation()\r\n \"\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 <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 + '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 </div>\r\n </div>\r\n </thead>\r\n <div\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <cdk-virtual-scroll-viewport\r\n [itemSize]=\"nestedTablerowHeight\"\r\n class=\"viewport\"\r\n [style.height.px]=\"\r\n (row?.detail?.result?.length < 5\r\n ? nestedTablerowHeight * row?.detail?.result?.length + 40\r\n : 300) + (hasHorizontalScroll ? -12 : 1)\r\n \"\r\n [style.width.px]=\"nestedHeader.offsetWidth - 10\"\r\n [style.minWidth.px]=\"nestedHeader.offsetWidth - 10\"\r\n >\r\n <div\r\n class=\"cursor-pointer border-below d-flex tr\"\r\n *cdkVirtualFor=\"let d of row?.detail?.result; trackBy: trackById\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.width.px]=\"nestedHeader?.offsetWidth\"\r\n [style.minWidth.px]=\"nestedHeader?.offsetWidth\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n (contextmenu)=\"onRightClick($event, d)\"\r\n >\r\n <div\r\n class=\"px-4 py-0 td\"\r\n *ngFor=\"let col of previewNestedCols; let j = index\"\r\n [style.fontSize.px]=\"nestedTablerowFontsize\"\r\n [attr.field]=\"col.field\"\r\n [style.width.px]=\"col?.width || 250\"\r\n [style.minWidth.px]=\"col?.width || 250\"\r\n [style.maxWidth.px]=\"col?.width || 250\"\r\n >\r\n <div\r\n [style.height.px]=\"nestedTablerowHeight - 1\"\r\n [style.max-width.px]=\"col?.width\"\r\n class=\"d-flex align-items-center\"\r\n >\r\n <!-- {{ d[col.field] || (col.is_amount ? 0 : \"-\") }} -->\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(d, col.field) | date : dateFormat)\r\n : getNestedValue(d, col.field) || '-'\r\n \"\r\n >\r\n <ng-container *ngIf=\"col.type !== 'image'\">\r\n <ng-container *ngIf=\"col.is_amount\">{{\r\n currencySymbol\r\n }}</ng-container>\r\n {{\r\n !isNestedValueArray(d, col.field)\r\n ? col.type === 'date'\r\n ? (isDate(getNestedValue(d, col.field))\r\n ? (getNestedValue(d, col.field) | date: dateFormat)\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n '-'))\r\n : (getNestedValue(d, col.field)?.value ||\r\n getNestedValue(d, col.field)?.name ||\r\n getNestedValue(d, col.field) ||\r\n (col.is_amount ? 0: '-'))\r\n : (getNestedValue(d, col.field)?.[0]?.department_name ||\r\n getNestedValue(d, col.field)?.[0]?.roleName || getNestedValue(d, col.field)?.[0]?.full_name ||\r\n '-')\r\n }}\r\n </ng-container>\r\n <ng-container *ngIf=\"false\">\r\n {{ getTotalAmount(col) }}\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: d,\r\n col: col,\r\n }\r\n \"\r\n ></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </cdk-virtual-scroll-viewport>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #leftRightNestedPlaceholder let-row>\r\n <table\r\n class=\"nested-table table table-sm w-100 mb-0\"\r\n [style.backgroundColor]=\"bodyBackgroundColor\"\r\n [style.height.px]=\"\r\n gridType == 'Assets'\r\n ? (nestedTableContainer?.nativeElement?.offsetHeight ?? 0) + 12\r\n : (taskManagementContainer?.nativeElement?.offsetHeight ?? 0)\r\n \"\r\n >\r\n <!-- <div class=\"thead\">\r\n <div\r\n class=\"tr d-flex border-below\"\r\n [style.height.px]=\"nestedTableHeaderRowHeight\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"th\" *ngFor=\"let _ of [1, 2, 3, 4, 5]\"></div>\r\n </div>\r\n </div> -->\r\n <!-- <div class=\"tbody\">\r\n <div\r\n class=\"tr border-below\"\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n *ngFor=\"let _ of row?.detail?.result\"\r\n [style.backgroundColor]=\"headerBackgroundColor\"\r\n >\r\n <div class=\"td\" *ngFor=\"let __ of [1, 2, 3, 4, 5]\" class=\"py-0\">\r\n <span\r\n [style.height.px]=\"nestedTablerowHeight\"\r\n [style.max-width.px]=\"nestedTablerowHeight\"\r\n ></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </table>\r\n</ng-template>\r\n\r\n<ng-template #taskManagementTemplate let-taskDetails=\"taskDetails\">\r\n <div\r\n class=\"p-4\"\r\n #taskManagementContainer\r\n [style.backgroundColor]=\"nestedTableHeaderBackgroundColor\"\r\n [style.fontFaimly]=\"fontFaimly\"\r\n >\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Description</div>\r\n <!-- <div class=\"item-content firstDiv\">\r\n {{ taskDetails.description }}\r\n </div> -->\r\n <p\r\n [style.fontSize]=\"bodyTextFontsSize\"\r\n class=\"item-content firstDiv taskDescription pe-4\"\r\n [innerHTML]=\"getSafeComment(taskDetails?.editor_description)\"\r\n (click)=\"openFullImage($event)\"\r\n ></p>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">Attachments</div>\r\n <h5 *ngIf=\"taskDetails?.attachments?.length == 0\">\r\n No Attachments found\r\n </h5>\r\n <div\r\n *ngIf=\"taskDetails?.attachments?.length\"\r\n class=\"item-content d-flex flex-wrap\"\r\n style=\"gap: 10px\"\r\n >\r\n <a\r\n *ngFor=\"let attachement of taskDetails?.attachments; let i = index\"\r\n class=\"symbol-label fs-2 fw-semibold text-success cursor-pointer\"\r\n >\r\n <span\r\n title=\"{{ taskDetails?.attachments_name[i] || 'Attachment' }}\"\r\n (click)=\"downloadAttchment(attachement)\"\r\n [inlineSVG]=\"\r\n singleSpaAssetsPath +\r\n 'data-grid/document-icons/' +\r\n getExtention(attachement) +\r\n '.svg'\r\n \"\r\n >\r\n </span>\r\n </a>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"item-title\">\r\n Comments ({{ taskDetails?.comments?.length }})\r\n </div>\r\n <h5 *ngIf=\"taskDetails?.comments?.length == 0\">No Comments found</h5>\r\n <div *ngIf=\"taskDetails?.comments?.length\" class=\"item-content\">\r\n <div class=\"comment\" *ngFor=\"let comment of taskDetails.comments\">\r\n <div class=\"d-flex align-items-center pe-3\">\r\n <img\r\n class=\"pic image-input-wrapper\"\r\n [style.width.px]=\"rowHeight - 12\"\r\n [style.height.px]=\"rowHeight - 12\"\r\n *ngIf=\"comment?.comment_by.logo\"\r\n src=\"{{ comment?.comment_by.logo }}\"\r\n alt=\"{{ comment.comment_by.full_name }}\"\r\n />\r\n <!-- <app-default-image-placeholder *ngIf=\"!comment?.comment_by.logo\" title=\"{{ comment.comment_by.full_name }}\" [name]=\"comment.comment_by.full_name\"></app-default-image-placeholder> -->\r\n <span\r\n *ngIf=\"!comment?.comment_by.logo\"\r\n [ngClass]=\"getDynamicClass(comment.comment_by.full_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 title=\"{{ comment.comment_by.full_name }}\"\r\n >\r\n {{ getInitials(comment.comment_by.full_name) }}\r\n </span>\r\n </div>\r\n <div>\r\n <div class=\"comment-author fs-14px\">\r\n {{ comment?.comment_by.full_name }}\r\n </div>\r\n <div\r\n class=\"comment-content forCommentImg\"\r\n [innerHTML]=\"getSafeComment(comment.comment)\"\r\n ></div>\r\n <div class=\"comment-timestamp\">\r\n {{ comment.comment_date | date }}\r\n </div>\r\n <div class=\"comment-timestamp\">\r\n Replies: ({{ comment.replies.length }})\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";@import\"bootstrap/dist/css/bootstrap.min.css\";.data-grid-table-wrapper{height:100%;width:100%;border:1px solid #d9d9db;border-radius:12px;position:relative}.data-grid-header{position:sticky;top:0}.data-grid-header{display:flex}.header-row{display:grid;width:100%}.header-cell{display:flex;align-items:center;position:relative;width:100%;padding:8px 0 8px 8px;font-weight:700;border-bottom:1px solid #d9d9db;white-space:nowrap;min-width:80px;font-weight:600}.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;margin-right:4px}.group-header .resize-handle{top:25%}.h-100{height:100%}.data-grid-body{position:relative;overflow-y:auto;overflow-x:hidden}.cell{padding:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.data-grid-row{display:flex;width:100%;min-width:max-content;align-items:center;border-bottom:1px solid #d9d9db}.hovered-row{background-color:#ccc}.checkbox-row{border-bottom:#d9d9db}.w-100{width:100%}.data-grid-header-wrapper{display:flex;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none}.data-grid-header{display:flex;position:relative;z-index:1}.left-pinned,.right-pinned{position:sticky;top:0}.right-pinned-header{position:absolute;right:0;border-left:1px solid #d9d9db;z-index:unset}.left-pinned{left:0}.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{-webkit-user-select:none;user-select:none;display:flex}.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:#fff;scrollbar-width:none;-ms-overflow-style:none}.left-pinned-body::-webkit-scrollbar,.right-pinned-body::-webkit-scrollbar{display:none}.left-pinned-body{left:0}.border-end{border-right:1px solid #d9d9db!important}.right-pinned-body{right:0;border-left:1px solid #d9d9db}.fake-scroll-bar{height:14px;overflow:scroll;margin-bottom:10px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis}.select-all-checkbox-cell{width:50px;display:flex;justify-content:center;align-items:center;height:100%;border-right:1px solid #d9d9db}.select-all-checkbox-cell input{width:16px;height:14px}.border-below{border-bottom:1px solid #d9d9db!important}.three-dots{width:22px;height:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;margin-right:8px;cursor:pointer}.three-dots:hover{background-color:#ccc!important}.filter-icon-wrapper{min-height:22px;max-height:22px;min-width:22px;max-width:22px;display:flex;justify-content:center;align-items:center;border-radius:3px;cursor:pointer;transition:background-color .3s ease}.filter-icon-wrapper:hover{background-color:#ccc}.column-menu,.filter-menu{box-shadow:0 0 16px #00000026;border-radius:4px}.column-menu{background:#fff;width:100%;width:240px;border:1px solid #ddd;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;padding:4px 0;font-size:14px;position:fixed}.column-menu-item{padding:8px 12px;cursor:pointer;display:flex;align-items:center;transition:background-color .2s ease}.column-menu-item:hover{background-color:#deebf7}.pin-parent{position:relative;width:100%!important}.column-submenu{position:absolute;top:0;left:100%;background:#fff;border:1px solid #ddd;width:130px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;display:none;padding:4px 0;z-index:10;border-radius:4px}.pin-parent:hover .column-submenu{display:block}.filter-menu-container{position:fixed;width:210px;background:#fff;border:1px solid #ddd;border-radius:4px;padding:12px;box-shadow:0 0 16px #00000026;border:1px solid #d9d9db;z-index:1000;font-size:14px}.filter-menu-header{font-weight:600;margin-bottom:10px}.filter-dropdown-section{max-height:350px;overflow-y:auto}.dropdown-options{overflow-y:auto;scrollbar-width:thin;height:100%}.filter-text-section select,.filter-text-section input{width:100%}.filter-radio-inputs{width:14px!important;height:14px!important}.right-menu{border-left:1px solid #d9d9db;font-size:14px}.border-start{border-left:1px solid #d9d9db!important}.column-panel-item{font-size:.875rem;color:#333}.toggle-icon{cursor:pointer;transition:transform .2s ease}.toggle-icon.rotate{transform:rotate(90deg)}.grab-icon{cursor:grab;color:#6c757d}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cursor-pointer{cursor:pointer}.pivot-mode{height:48px}.chevron-wrapper{width:30px;height:20px;cursor:pointer;border-radius:3px;display:flex;justify-content:center;align-items:center;transition:background-color .3s ease;margin-right:8px}.chevron-wrapper:hover{background-color:#cac7c7}.chevron-wrapper i{font-size:14px}.column-panel-body{height:70%;overflow:auto;scrollbar-width:thin}.side-menue-text{transform:rotate(90deg);position:relative;font-weight:700;margin-top:40px}.columns-button{padding-top:20px;padding-bottom:35px;width:29px}.fake-scroll-content{height:12px}.fake-scrollbar{width:25px}.fake-scrollbar div{min-width:1px}.fake-horizintal-scrollbar div{min-height:1px}.side-filter-columns-wrapper{height:calc(100% - 25px)}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;justify-content:center;align-items:center;z-index:1050}.custom-modal-overlay .moda-header{background-color:#f8f8f8}.custom-modal-content{background-color:#fff;border-radius:8px;min-width:300px;max-width:400px;box-shadow:0 5px 20px #0000004d}.overlay-scrollable{height:250px;overflow:auto}.footer-row{border-top:1px solid #d9d9db;padding-left:32px}.fake-horizintal-scrollbar{position:relative;bottom:17px;overflow-x:auto;overflow-y:hidden;height:17px}.border-dashed{border:1px dashed #d9d9db}.cdk-drag-preview{box-sizing:border-box!important;border-radius:4px!important;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f!important;background-color:#f3f4f5!important;border:1px solid #d9d9db!important;z-index:9999!important}.data-grid-header-wrapper ::ng-deep .cdk-drag-placeholder{display:block!important;background:#fff!important;opacity:1!important}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)!important}.top-row-grouping-placeholder{display:flex;align-items:center;border-radius:12px;font-size:14px;padding-inline:6px;border:1px solid #d9d9db}.top-row-grouping-placeholder .bi-x{cursor:pointer;color:#7a7a7a}.top-row-grouping-placeholder .bi-x:hover{color:#111}.right-pinned-body-wrapper{position:absolute;right:0}.actions-dropdown{position:absolute;right:200px;z-index:1050;background-color:#fff;border-radius:8px!important;cursor:default}.bg-fff{background-color:#fff}.actions-dropdown-setting{right:250px}.action-button{background-color:#007cf5!important;border-radius:8px!important;padding:8px 16px!important;font-size:14px;height:32px;align-items:center}.global-search{max-width:380px!important;display:flex!important;align-items:center!important}.global-search span{margin-top:-4px!important}.global-search input{padding-left:28px;border-radius:8px!important}.global-search input:focus{outline:none!important;box-shadow:none!important}.active .top-icon ::ng-deep svg path{stroke:#007cf5!important}.dropdown-menu{background-color:#fff!important;border:1px solid #d9d9db!important;border-radius:8px!important}.custom-menu{width:220px;border-radius:8px;padding:4px 0;background-color:#fff}.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;background:#fff;border-radius:8px!important}.actions-dropdown,.table-layout,.custom-menu,.dropdown-menu{background:#fff;border-radius:8px!important;border:1px solid #ccc!important;background-color:#fff}.preview-box{width:40px;height:10px;border-radius:3px;background-color:transparent;transition:background-color .2s ease-in-out}.btn-check:checked+label .preview-box{background-color:var(--bs-primary)}.preview-box{width:40px;height:10px;border-radius:3px;border:2px solid transparent;transition:border-color .2s ease-in-out}#small:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#medium:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}#large:checked+label .preview-box{border-color:#007cf5!important;background-color:transparent!important}.btn-check:checked+.btn{background-color:transparent!important;border-color:#007cf5!important}.layout-button{padding:8px 28px!important;width:82px;border-radius:8px!important}.show-hide-table-label{position:sticky;top:0;z-index:99;background:#fff}.cursor-grap{cursor:grabbing}.pagination-container{display:flex;align-items:center;gap:12px;font-size:13px;color:#333}.page-size select{padding:3px 6px;border:1px solid #ccc;border-radius:6px;background:#fff;font-size:13px}.page-info{margin-left:10px}.page-buttons{display:flex;gap:4px;margin-left:auto;align-items:center}.page-buttons button{padding:3px 8px;border:1px solid #ccc;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;line-height:1.2}.page-buttons button.active{background:#eee;font-weight:600}.page-buttons button:disabled{opacity:.5;cursor:not-allowed}.page-buttons span{padding:0 6px;color:#666}.page-size .separator{padding:0 8px;border-right:1px solid #ccc;margin-right:8px}.page-size .separator .actions-dropdown{position:fixed;right:200px;z-index:1050;background-color:#fff}.fs-14px{font-size:14px}.fs-12px{font-size:12px!important}.save-preset-dropdown{background:#fff;color:#111!important;right:0;font-weight:400!important;text-align:left!important;max-width:250px!important;text-wrap:auto!important;top:14px;font-size:14px!important}.add-filter-button{height:28px;cursor:pointer;border-radius:4px}.add-filter-button:hover,.button-filter:hover{color:#000!important}.button-filter:hover ::ng-deep svg path{stroke:#000!important}.table-layout .dropdown-item{border-radius:0!important;padding-inline:16px!important;font-size:14px;padding-block:6px!important}.table-layout .dropdown-item:hover{background-color:transparent!important}.filter-serach-inpt{max-height:230px!important;overflow:auto;scrollbar-width:thin;padding-top:4px;background-color:#f7f7f7;border-color:#dedede;border-radius:8px}.filter-serach-inpt .badge{color:#007cf5!important;background-color:#e6f2ff!important;border-radius:8px!important;padding:8px!important;font-weight:500!important;font-size:12px!important;height:24px!important}.filter-serach-inpt .badge ::ng-deep svg{cursor:pointer}.filter-serach-inpt .badge ::ng-deep svg:hover path{stroke:#040081!important}.filter-serach-inpt input{background-color:#f7f7f7;padding:0;height:26px;margin-top:-5px}.text-filter select{border:0}.text-filter select option{font-size:14px;font-weight:500}.text-filter select:focus{border:0}.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;z-index:1050;border:1px solid #dedede;border-radius:8px;padding:12px 14px;box-shadow:0 2px 8px #00000026;max-height:400px;overflow:auto}.full-text-box ul{max-height:400px}.full-text-content{border-radius:8px;max-height:70vh;overflow:auto;white-space:pre-wrap}.pic{border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:22px}.pic-comb2{background-color:#fbe7bf;color:#fd7f31}.pic-comb1{background-color:#d9ecbf;color:#65b500}.pic-comb4{background-color:#fdd3d7;color:#f64e60}.w-40px{width:40px}.h-40px{height:40px}.pic{border-radius:50%;overflow:hidden}.image-placeholder .pic{font-size:14px;font-weight:600;letter-spacing:.5px}.header-cell{font-weight:600}.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;display:flex;justify-content:center;z-index:1000}.taskbar .action-btn{transition:opacity text-decoration .3s ease}.taskbar .action-btn:hover{text-decoration:underline;opacity:.8}.taskbar .delete{color:#ea0000}.selected-count,.action-btn,.dropdown-content a{font-weight:500;font-size:14px}.selected-rows-action-bar{background-color:#1a1a1a;color:#fff;padding:4px 24px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:24px;box-shadow:0 -4px 12px #00000026}.selected-rows-action-bar .btn:active,.selected-rows-action-bar .btn:focus{outline:0!important;border:0!important;border-color:transparent!important}.selected-rows-action-bar .action-btn{color:#fff!important}.cell .dropdown-menu,.cell .form-select,.cell input{color:#000!important}.cell input::placeholder{color:#727272!important}.cell .badge{border-radius:50px!important;height:26px;align-items:center}.cell .badge-danger{color:#ea5353!important;border:1px solid #ea5353!important;background-color:#ff00000d!important}.cell .badge-success{background-color:#84ca8130!important;border:1.5px solid rgb(70,227,114)!important;color:#46e372!important}.cell .badge-warning{background-color:#fff3dc!important;color:orange!important;border:1px solid #ffa000!important}.cell .badge-info{color:#00bad1;background-color:#e8fbfd;border:1px solid #00bad1}.cell .badge-secondary{color:#6c757d;background-color:#f1f3f5;border:1px solid #6c757d}.header-tag ::ng-deep svg path{stroke:#727272!important}.cross-secondary:hover ::ng-deep svg path{stroke:#000!important}.disable-sorting{pointer-events:none;opacity:.5}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{background-color:transparent!important}input.is-invalid:focus{border:2.5px solid red!important;outline:none}.table-cell input.is-invalid:focus{border:2.5px solid red!important;outline-color:red!important;outline:none!important;box-shadow:none!important}.active-for-editing:has(input.is-invalid:focus){outline:none!important;box-shadow:none!important;border:0!important}.selected-cell,.row-selected{background-color:#c2e0fe}.first-row-selected{border-top:2px solid #2196f3!important}.last-row-selected{border-bottom:2px solid #2196f3!important}.left-selection-border{border-left:2px solid #2196f3!important}.s-no{font-size:14px;font-weight:500}.top-border{border-top:2px solid #2196f3!important}.bottom-border{border-bottom:2px solid #2196f3!important}.left-border{border-left:2px solid #2196f3!important}.border-left{border-left:1px solid #d9d9db}.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 .center-section .table .tbody .tr:hover .td{background-color:#f0f8ff!important}.editing-dropdown-search-input input:focus{border:1px solid #86b7fe!important}.nested-table .thead{position:sticky;top:0}.dropdown-wrapper{position:relative;display:inline-block}.btn-icon{background:transparent;border:0;padding:.25rem .5rem;cursor:pointer}.custom-dropdown-menu{position:absolute;right:0;top:calc(100% + 6px);min-width:200px;list-style:none;margin:0;padding:.25rem 0;background:#fff!important;border:1px solid rgba(0,0,0,.08);box-shadow:0 6px 18px #00000014;border-radius:.35rem;z-index:1200}.custom-dropdown-menu .dropdown-item{display:block;width:100%;padding:.5rem 1rem;text-align:left;background:transparent;border:none}.custom-dropdown-menu .dropdown-item:hover{background:#00000008}.cell-editing-dropdown-menu .dropdown-item{width:99%}.cell-editing-dropdown-menu .selected{background-color:#f0f8ff}.confirm-block{padding:0}.center-nested-table .tr:hover .td{background-color:#f0f8ff}.table ::ng-deep .cdk-drag-placeholder{background-color:#fff!important}.assets-pic{border-radius:8px!important}.fullscreen-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000c;display:flex;align-items:center;justify-content:center;z-index:1000;cursor:zoom-out}.fullscreen-img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 15px #00000080}.position-sticky{z-index:2}.viewport{display:block!important;overflow:visible!important}.nested-table ::ng-deep .cdk-virtual-scroll-content-wrapper{padding:0!important}.nested-table ::ng-deep .cdk-virtual-scroll-viewport{overflow-x:hidden!important}.disabled-search-input{background-color:#f5f5f5;cursor:pointer!important}.right-click-menu-icons ::ng-deep svg path{stroke-width:2!important}.loader{animation:rotate 1s infinite;height:50px;width:50px}.loader:before,.loader:after{border-radius:50%;content:\"\";display:block;height:20px;width:20px}.loader:before{animation:ball1 1s infinite;background-color:#fff;box-shadow:30px 0 #ff3d00;margin-bottom:10px}.loader:after{animation:ball2 1s infinite;background-color:#ff3d00;box-shadow:30px 0 #fff}@keyframes rotate{0%{transform:rotate(0) scale(.8)}50%{transform:rotate(360deg) scale(1.2)}to{transform:rotate(720deg) scale(.8)}}@keyframes ball1{0%{box-shadow:30px 0 #ff3d00}50%{box-shadow:0 0 #ff3d00;margin-bottom:0;transform:translate(15px,15px)}to{box-shadow:30px 0 #ff3d00;margin-bottom:10px}}@keyframes ball2{0%{box-shadow:30px 0 #fff}50%{box-shadow:0 0 #fff;margin-top:-20px;transform:translate(15px,15px)}to{box-shadow:30px 0 #fff;margin-top:0}}.rows-grouping-top-container ::ng-deep .cdk-drag-placeholder{opacity:.7!important}.action-button{background-color:#6f61cf!important;color:#fff!important;border-radius:6px!important;font-weight:500!important;margin-top:-4px}.action-button:hover{background-color:#6a5fb3!important}.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}::ng-deep .nav-tabs .nav-link{border:none!important;border-bottom:2px solid transparent!important;border-radius:0!important;background:transparent!important}::ng-deep .nav-tabs .nav-link:hover,::ng-deep .nav-tabs .nav-link:focus{border:none!important;border-bottom:2px solid transparent!important;outline:none!important;background:transparent!important}::ng-deep .nav-tabs .nav-link.active{border:none!important;border-bottom:2px solid var(--bs-primary)!important;background:transparent!important;color:var(--bs-primary)!important}.open-top{top:-150%!important}.muted{color:#7a7a7a!important}.item-title{font-size:1.2em;font-weight:700;margin-bottom:10px}.item-image{width:100%;border-radius:10px}.comment{display:flex;align-items:center;margin-bottom:10px}.comment-avatar{width:40px;height:40px;border-radius:50%;margin-right:10px}.comment-author{font-weight:700}.comment-content{font-size:.9em;line-height:1.4}.comment-timestamp{font-size:.8em;color:#888;margin-left:auto}.des_low{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:242px;display:block;text-transform:capitalize!important}.firstDiv{word-break:break-word;overflow-wrap:break-word;white-space:normal}.container{display:flex;flex-wrap:wrap;margin:20px;gap:20px;background-color:#fff;padding:20px;border-radius:10px}.item{width:calc(33.33% - 20px);background-color:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 5px #0000001a}.forCommentImg{width:70px;border-radius:16px;margin:8px 0;cursor:pointer}.image-modal img{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 4px 10px #00000080}.full-image-modal{position:fixed;background:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.full-image-modal .full-image{max-width:90%;max-height:90%;border-radius:8px;box-shadow:0 0 10px #fff3}.item-content{font-size:14px;line-height:1.5;max-height:220px;overflow-y:auto}.image-modal.full-image-modal{position:fixed;width:100vw;height:100vh;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:9999;overflow:hidden;cursor:zoom-out}.image-modal.full-image-modal img{border-radius:8px;box-shadow:0 4px 20px #0006;object-fit:contain;transition:transform .3s ease}.image-modal.full-image-modal img:hover{transform:scale(1.02)}::ng-deep .custom-overlay-wrapper .custom-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:9999}::ng-deep .custom-overlay-wrapper .custom-modal{background:#fff;border-radius:12px;box-shadow:0 8px 25px #0003;width:360px;max-width:90%;padding:24px;text-align:center;animation:fadeInScale .25s ease}::ng-deep .custom-overlay-wrapper .custom-modal-body .modal-message{font-size:16px;margin-bottom:20px;color:#333}::ng-deep .custom-overlay-wrapper .modal-actions{display:flex;justify-content:center;gap:12px}::ng-deep .custom-overlay-wrapper .modal-actions button{min-width:90px;padding:8px 14px;border-radius:6px;border:none;font-weight:500;cursor:pointer;transition:background-color .2s ease}::ng-deep .custom-overlay-wrapper .btn-confirm{background-color:#007bff;color:#fff}::ng-deep .custom-overlay-wrapper .btn-confirm:hover{background-color:#0069d9}::ng-deep .custom-overlay-wrapper .btn-cancel{background-color:#e4e4e4;color:#333}::ng-deep .custom-overlay-wrapper .btn-cancel:hover{background-color:#d6d6d6}@keyframes fadeInScale{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.clear-btn{background:linear-gradient(135deg,#f53545,#f53545);border:none;color:#fff;font-size:13px;padding:3px 6px;border-radius:20px;font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px #ff5f6d66;position:relative;bottom:4px}.clear-btn:hover{transform:translateY(-2px);box-shadow:0 4px 10px #ff5f6d99;background:linear-gradient(135deg,#f53545,#f53545)}.clear-btn i{font-size:16px;vertical-align:middle}.cell-editin-dropdown .deopdown-item{width:100%!important;box-shadow:none!important;border-radius:4px;cursor:pointer;padding-block:8px!important}.cell-editin-dropdown .deopdown-item:hover{background-color:#f1f1f1}\n"] }]
6070
6188
  }], ctorParameters: function () { return [{ type: SplitColumnsService }, { type: i0.ChangeDetectorRef }, { type: CommonService }, { type: i0.ElementRef }, { type: i0.NgZone }, { type: CopyServiceService }, { type: i0.Renderer2 }, { type: i4.DomSanitizer }, { type: ExportService }, { type: i6.DatePipe }, { type: FormatCurrencyPipe }]; }, propDecorators: { rowAnimation: [{
6071
6189
  type: Input
6072
6190
  }], paginationConfig: [{
@@ -6334,13 +6452,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
6334
6452
 
6335
6453
  class DataGridModule {
6336
6454
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
6337
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, declarations: [DataGridComponent, FilterPipe, CellHostDirective, CellRenderInitDirective, FormatCurrencyPipe], imports: [CommonModule, FormsModule, DragDropModule, i10.InlineSVGModule, ScrollingModule], exports: [DataGridComponent] }); }
6455
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, declarations: [DataGridComponent, FilterPipe, CellHostDirective, CellRenderInitDirective, CellEditorDirective, FormatCurrencyPipe], imports: [CommonModule, FormsModule, DragDropModule, i10.InlineSVGModule, ScrollingModule], exports: [DataGridComponent] }); }
6338
6456
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, providers: [FormatCurrencyPipe, DatePipe], imports: [CommonModule, FormsModule, DragDropModule, InlineSVGModule.forRoot(), ScrollingModule] }); }
6339
6457
  }
6340
6458
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataGridModule, decorators: [{
6341
6459
  type: NgModule,
6342
6460
  args: [{
6343
- declarations: [DataGridComponent, FilterPipe, CellHostDirective, CellRenderInitDirective, FormatCurrencyPipe],
6461
+ declarations: [DataGridComponent, FilterPipe, CellHostDirective, CellRenderInitDirective, CellEditorDirective, FormatCurrencyPipe],
6344
6462
  imports: [CommonModule, FormsModule, DragDropModule, InlineSVGModule.forRoot(), ScrollingModule],
6345
6463
  exports: [DataGridComponent],
6346
6464
  providers: [FormatCurrencyPipe, DatePipe],