grid view
This commit is contained in:
		
							parent
							
								
									e6779e8f34
								
							
						
					
					
						commit
						4f82ae8698
					
				| @ -1,5 +1,223 @@ | ||||
| <div style="display: block;"> | ||||
|   <div class="dg-wrapper"> | ||||
|     <!-- Filter Controls Section --> | ||||
|     <div class="filter-section" *ngIf="hasActiveFilters()"> | ||||
|       <!-- Base Filters --> | ||||
|       <div class="filter-group" *ngIf="baseFilters && baseFilters.length > 0"> | ||||
|         <h4>Base Filters</h4> | ||||
|         <div class="filter-controls"> | ||||
|           <div *ngFor="let filter of baseFilters" class="filter-item"> | ||||
|             <div class="filter-label">{{ filter.field }} ({{ filter.type || 'text' }})</div> | ||||
|              | ||||
|             <!-- Text Filter --> | ||||
|             <div *ngIf="!filter.type || filter.type === 'text'" class="filter-input"> | ||||
|               <input type="text"  | ||||
|                      [(ngModel)]="filter.value"  | ||||
|                      (ngModelChange)="onBaseFilterChange(filter)" | ||||
|                      [placeholder]="filter.field" | ||||
|                      class="clr-input filter-text-input"> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Dropdown Filter --> | ||||
|             <div *ngIf="filter.type === 'dropdown'" class="filter-input"> | ||||
|               <select [(ngModel)]="filter.value"  | ||||
|                       (ngModelChange)="onBaseFilterChange(filter)" | ||||
|                       class="clr-select filter-select"> | ||||
|                 <option value="">Select {{ filter.field }}</option> | ||||
|                 <option *ngFor="let option of getFilterOptions(filter)" [value]="option">{{ option }}</option> | ||||
|               </select> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Multi-Select Filter --> | ||||
|             <div *ngIf="filter.type === 'multiselect'" class="filter-input multiselect-container"> | ||||
|               <div class="checkbox-group"> | ||||
|                 <div *ngFor="let option of getFilterOptions(filter)" class="checkbox-item"> | ||||
|                   <input type="checkbox"  | ||||
|                          [checked]="isOptionSelected(filter, option)"  | ||||
|                          (change)="onMultiSelectChange(filter, option, $event)" | ||||
|                          [id]="'base-' + filter.field + '-' + option"  | ||||
|                          class="clr-checkbox"> | ||||
|                   <label [for]="'base-' + filter.field + '-' + option" class="checkbox-label">{{ option }}</label> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Date Range Filter --> | ||||
|             <div *ngIf="filter.type === 'date-range'" class="filter-input date-range"> | ||||
|               <div class="date-input-group"> | ||||
|                 <input type="date"  | ||||
|                        [(ngModel)]="filter.value.start"  | ||||
|                        (ngModelChange)="onDateRangeChange(filter, { start: $event, end: filter.value.end })" | ||||
|                        placeholder="Start Date" | ||||
|                        class="clr-input filter-date"> | ||||
|                 <span class="date-separator">to</span> | ||||
|                 <input type="date"  | ||||
|                        [(ngModel)]="filter.value.end"  | ||||
|                        (ngModelChange)="onDateRangeChange(filter, { start: filter.value.start, end: $event })" | ||||
|                        placeholder="End Date" | ||||
|                        class="clr-input filter-date"> | ||||
|               </div> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Toggle Filter --> | ||||
|             <div *ngIf="filter.type === 'toggle'" class="filter-input toggle"> | ||||
|               <input type="checkbox"  | ||||
|                      [(ngModel)]="filter.value"  | ||||
|                      (ngModelChange)="onToggleChange(filter, $event)" | ||||
|                      clrToggle  | ||||
|                      class="clr-toggle"> | ||||
|               <label class="toggle-label">{{ filter.field }}</label> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|        | ||||
|       <!-- Drilldown Filters --> | ||||
|       <div class="filter-group" *ngIf="drilldownFilters && drilldownFilters.length > 0 && currentDrilldownLevel > 0"> | ||||
|         <h4>Drilldown Filters</h4> | ||||
|         <div class="filter-controls"> | ||||
|           <div *ngFor="let filter of drilldownFilters" class="filter-item"> | ||||
|             <div class="filter-label">{{ filter.field }} ({{ filter.type || 'text' }})</div> | ||||
|              | ||||
|             <!-- Text Filter --> | ||||
|             <div *ngIf="!filter.type || filter.type === 'text'" class="filter-input"> | ||||
|               <input type="text"  | ||||
|                      [(ngModel)]="filter.value"  | ||||
|                      (ngModelChange)="onDrilldownFilterChange(filter)" | ||||
|                      [placeholder]="filter.field" | ||||
|                      class="clr-input filter-text-input"> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Dropdown Filter --> | ||||
|             <div *ngIf="filter.type === 'dropdown'" class="filter-input"> | ||||
|               <select [(ngModel)]="filter.value"  | ||||
|                       (ngModelChange)="onDrilldownFilterChange(filter)" | ||||
|                       class="clr-select filter-select"> | ||||
|                 <option value="">Select {{ filter.field }}</option> | ||||
|                 <option *ngFor="let option of getFilterOptions(filter)" [value]="option">{{ option }}</option> | ||||
|               </select> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Multi-Select Filter --> | ||||
|             <div *ngIf="filter.type === 'multiselect'" class="filter-input multiselect-container"> | ||||
|               <div class="checkbox-group"> | ||||
|                 <div *ngFor="let option of getFilterOptions(filter)" class="checkbox-item"> | ||||
|                   <input type="checkbox"  | ||||
|                          [checked]="isOptionSelected(filter, option)"  | ||||
|                          (change)="onMultiSelectChange(filter, option, $event)" | ||||
|                          [id]="'drilldown-' + filter.field + '-' + option"  | ||||
|                          class="clr-checkbox"> | ||||
|                   <label [for]="'drilldown-' + filter.field + '-' + option" class="checkbox-label">{{ option }}</label> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Date Range Filter --> | ||||
|             <div *ngIf="filter.type === 'date-range'" class="filter-input date-range"> | ||||
|               <div class="date-input-group"> | ||||
|                 <input type="date"  | ||||
|                        [(ngModel)]="filter.value.start"  | ||||
|                        (ngModelChange)="onDateRangeChange(filter, { start: $event, end: filter.value.end })" | ||||
|                        placeholder="Start Date" | ||||
|                        class="clr-input filter-date"> | ||||
|                 <span class="date-separator">to</span> | ||||
|                 <input type="date"  | ||||
|                        [(ngModel)]="filter.value.end"  | ||||
|                        (ngModelChange)="onDateRangeChange(filter, { start: filter.value.start, end: $event })" | ||||
|                        placeholder="End Date" | ||||
|                        class="clr-input filter-date"> | ||||
|               </div> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Toggle Filter --> | ||||
|             <div *ngIf="filter.type === 'toggle'" class="filter-input toggle"> | ||||
|               <input type="checkbox"  | ||||
|                      [(ngModel)]="filter.value"  | ||||
|                      (ngModelChange)="onToggleChange(filter, $event)" | ||||
|                      clrToggle  | ||||
|                      class="clr-toggle"> | ||||
|               <label class="toggle-label">{{ filter.field }}</label> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|        | ||||
|       <!-- Layer Filters --> | ||||
|       <div class="filter-group" *ngIf="hasActiveLayerFilters()"> | ||||
|         <h4>Layer Filters</h4> | ||||
|         <div class="filter-controls"> | ||||
|           <div *ngFor="let filter of getActiveLayerFilters()" class="filter-item"> | ||||
|             <div class="filter-label">{{ filter.field }} ({{ filter.type || 'text' }})</div> | ||||
|              | ||||
|             <!-- Text Filter --> | ||||
|             <div *ngIf="!filter.type || filter.type === 'text'" class="filter-input"> | ||||
|               <input type="text"  | ||||
|                      [(ngModel)]="filter.value"  | ||||
|                      (ngModelChange)="onLayerFilterChange(filter)" | ||||
|                      [placeholder]="filter.field" | ||||
|                      class="clr-input filter-text-input"> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Dropdown Filter --> | ||||
|             <div *ngIf="filter.type === 'dropdown'" class="filter-input"> | ||||
|               <select [(ngModel)]="filter.value"  | ||||
|                       (ngModelChange)="onLayerFilterChange(filter)" | ||||
|                       class="clr-select filter-select"> | ||||
|                 <option value="">Select {{ filter.field }}</option> | ||||
|                 <option *ngFor="let option of getFilterOptions(filter)" [value]="option">{{ option }}</option> | ||||
|               </select> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Multi-Select Filter --> | ||||
|             <div *ngIf="filter.type === 'multiselect'" class="filter-input multiselect-container"> | ||||
|               <div class="checkbox-group"> | ||||
|                 <div *ngFor="let option of getFilterOptions(filter)" class="checkbox-item"> | ||||
|                   <input type="checkbox"  | ||||
|                          [checked]="isOptionSelected(filter, option)"  | ||||
|                          (change)="onMultiSelectChange(filter, option, $event)" | ||||
|                          [id]="'layer-' + filter.field + '-' + option"  | ||||
|                          class="clr-checkbox"> | ||||
|                   <label [for]="'layer-' + filter.field + '-' + option" class="checkbox-label">{{ option }}</label> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Date Range Filter --> | ||||
|             <div *ngIf="filter.type === 'date-range'" class="filter-input date-range"> | ||||
|               <div class="date-input-group"> | ||||
|                 <input type="date"  | ||||
|                        [(ngModel)]="filter.value.start"  | ||||
|                        (ngModelChange)="onDateRangeChange(filter, { start: $event, end: filter.value.end })" | ||||
|                        placeholder="Start Date" | ||||
|                        class="clr-input filter-date"> | ||||
|                 <span class="date-separator">to</span> | ||||
|                 <input type="date"  | ||||
|                        [(ngModel)]="filter.value.end"  | ||||
|                        (ngModelChange)="onDateRangeChange(filter, { start: filter.value.start, end: $event })" | ||||
|                        placeholder="End Date" | ||||
|                        class="clr-input filter-date"> | ||||
|               </div> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Toggle Filter --> | ||||
|             <div *ngIf="filter.type === 'toggle'" class="filter-input toggle"> | ||||
|               <input type="checkbox"  | ||||
|                      [(ngModel)]="filter.value"  | ||||
|                      (ngModelChange)="onToggleChange(filter, $event)" | ||||
|                      clrToggle  | ||||
|                      class="clr-toggle"> | ||||
|               <label class="toggle-label">{{ filter.field }}</label> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|        | ||||
|       <!-- Clear Filters Button --> | ||||
|       <div class="filter-actions"> | ||||
|         <button class="btn btn-sm btn-outline" (click)="clearAllFilters()">Clear All Filters</button> | ||||
|       </div> | ||||
|     </div> | ||||
|      | ||||
|     <div class="clr-row"> | ||||
|       <div class="clr-col-8"> | ||||
|         <h3>{{charttitle || 'Data Grid'}}</h3> | ||||
|  | ||||
| @ -1,28 +1,132 @@ | ||||
| // Add styles for drilldown navigation | ||||
| .alert-info { | ||||
|   background-color: #dcedf7; | ||||
|   border-color: #a3d4f5; | ||||
|   color: #21333b; | ||||
| .filter-section { | ||||
|   margin-bottom: 20px; | ||||
|   padding: 15px; | ||||
|   border: 1px solid #ddd; | ||||
|   border-radius: 4px; | ||||
|   background-color: #f9f9f9; | ||||
| } | ||||
| 
 | ||||
| .alert-info .alert-icon { | ||||
|   color: #0072a3; | ||||
| .filter-group { | ||||
|   margin-bottom: 15px; | ||||
|    | ||||
|   h4 { | ||||
|     margin-top: 0; | ||||
|     margin-bottom: 10px; | ||||
|     color: #333; | ||||
|     font-weight: 600; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .btn-link { | ||||
|   color: #0072a3; | ||||
|   text-decoration: none; | ||||
| .filter-controls { | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 15px; | ||||
| } | ||||
| 
 | ||||
| .btn-link:hover { | ||||
|   color: #00567a; | ||||
|   text-decoration: underline; | ||||
| .filter-item { | ||||
|   flex: 1 1 300px; | ||||
|   min-width: 250px; | ||||
|   padding: 10px; | ||||
|   background: white; | ||||
|   border: 1px solid #e0e0e0; | ||||
|   border-radius: 4px; | ||||
| } | ||||
| 
 | ||||
| .filter-label { | ||||
|   font-weight: 500; | ||||
|   margin-bottom: 8px; | ||||
|   color: #555; | ||||
|   font-size: 14px; | ||||
| } | ||||
| 
 | ||||
| .filter-input { | ||||
|   width: 100%; | ||||
|    | ||||
|   .filter-text-input, | ||||
|   .filter-select, | ||||
|   .filter-date { | ||||
|     width: 100%; | ||||
|     padding: 6px 12px; | ||||
|     border: 1px solid #ccc; | ||||
|     border-radius: 4px; | ||||
|     font-size: 14px; | ||||
|   } | ||||
|    | ||||
|   .filter-select { | ||||
|     height: 34px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .multiselect-container { | ||||
|   .checkbox-group { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     gap: 5px; | ||||
|   } | ||||
|    | ||||
|   .checkbox-item { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     gap: 8px; | ||||
|      | ||||
|     .checkbox-label { | ||||
|       margin: 0; | ||||
|       font-size: 14px; | ||||
|       cursor: pointer; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .date-range { | ||||
|   .date-input-group { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     gap: 8px; | ||||
|   } | ||||
|    | ||||
|   .date-separator { | ||||
|     margin: 0 5px; | ||||
|     color: #777; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .toggle { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   gap: 8px; | ||||
|    | ||||
|   .toggle-label { | ||||
|     margin: 0; | ||||
|     font-size: 14px; | ||||
|     cursor: pointer; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .filter-actions { | ||||
|   margin-top: 15px; | ||||
|   padding-top: 15px; | ||||
|   border-top: 1px solid #eee; | ||||
|    | ||||
|   .btn { | ||||
|     font-size: 13px; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .dg-wrapper { | ||||
|   padding: 12px; | ||||
|   padding: 15px; | ||||
| } | ||||
| 
 | ||||
| .clr-row { | ||||
|   margin-bottom: 12px; | ||||
| clr-datagrid { | ||||
|   margin-top: 10px; | ||||
| } | ||||
| 
 | ||||
| // Responsive design | ||||
| @media (max-width: 768px) { | ||||
|   .filter-controls { | ||||
|     flex-direction: column; | ||||
|   } | ||||
|    | ||||
|   .filter-item { | ||||
|     min-width: 100%; | ||||
|   } | ||||
| } | ||||
| @ -66,6 +66,9 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | ||||
|   // Add subscriptions to unsubscribe on destroy
 | ||||
|   private subscriptions: Subscription[] = []; | ||||
| 
 | ||||
|   // Add a flag to track if filters have been initialized
 | ||||
|   private filtersInitialized: boolean = false; | ||||
| 
 | ||||
|   constructor( | ||||
|     private mainservice: UsergrpmaintainceService, | ||||
|     private dashboardService: Dashboard3Service, | ||||
| @ -102,6 +105,12 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | ||||
|     const drilldownYAxisChanged = changes.drilldownYAxis && !changes.drilldownYAxis.firstChange; | ||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.firstChange; | ||||
| 
 | ||||
|     // Initialize filter values if they haven't been initialized yet
 | ||||
|     if (!this.filtersInitialized && (changes.baseFilters || changes.drilldownFilters || changes.drilldownLayers)) { | ||||
|       this.initializeFilterValues(); | ||||
|       this.filtersInitialized = true; | ||||
|     } | ||||
| 
 | ||||
|     // Respond to input changes
 | ||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || | ||||
|       drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || | ||||
| @ -112,6 +121,84 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Initialize filter values with proper default values based on type
 | ||||
|   private initializeFilterValues(): void { | ||||
|     console.log('Initializing filter values'); | ||||
|      | ||||
|     // Initialize base filters
 | ||||
|     if (this.baseFilters) { | ||||
|       this.baseFilters.forEach(filter => { | ||||
|         if (filter.value === undefined || filter.value === null) { | ||||
|           switch (filter.type) { | ||||
|             case 'multiselect': | ||||
|               filter.value = []; | ||||
|               break; | ||||
|             case 'date-range': | ||||
|               filter.value = { start: null, end: null }; | ||||
|               break; | ||||
|             case 'toggle': | ||||
|               filter.value = false; | ||||
|               break; | ||||
|             default: | ||||
|               filter.value = ''; | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     // Initialize drilldown filters
 | ||||
|     if (this.drilldownFilters) { | ||||
|       this.drilldownFilters.forEach(filter => { | ||||
|         if (filter.value === undefined || filter.value === null) { | ||||
|           switch (filter.type) { | ||||
|             case 'multiselect': | ||||
|               filter.value = []; | ||||
|               break; | ||||
|             case 'date-range': | ||||
|               filter.value = { start: null, end: null }; | ||||
|               break; | ||||
|             case 'toggle': | ||||
|               filter.value = false; | ||||
|               break; | ||||
|             default: | ||||
|               filter.value = ''; | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     // Initialize layer filters
 | ||||
|     if (this.drilldownLayers) { | ||||
|       this.drilldownLayers.forEach(layer => { | ||||
|         if (layer.filters) { | ||||
|           layer.filters.forEach((filter: any) => { | ||||
|             if (filter.value === undefined || filter.value === null) { | ||||
|               switch (filter.type) { | ||||
|                 case 'multiselect': | ||||
|                   filter.value = []; | ||||
|                   break; | ||||
|                 case 'date-range': | ||||
|                   filter.value = { start: null, end: null }; | ||||
|                   break; | ||||
|                 case 'toggle': | ||||
|                   filter.value = false; | ||||
|                   break; | ||||
|                 default: | ||||
|                   filter.value = ''; | ||||
|               } | ||||
|             } | ||||
|           }); | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     console.log('Filter values initialized:', { | ||||
|       baseFilters: this.baseFilters, | ||||
|       drilldownFilters: this.drilldownFilters, | ||||
|       drilldownLayers: this.drilldownLayers | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   // Dynamic headers for the grid
 | ||||
| 
 | ||||
|   fetchGridData(): void { | ||||
| @ -628,6 +715,174 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | ||||
|       .replace(/^./, str => str.toUpperCase()); | ||||
|   } | ||||
| 
 | ||||
|   // Check if there are active filters
 | ||||
|   hasActiveFilters(): boolean { | ||||
|     return (this.baseFilters && this.baseFilters.length > 0) ||  | ||||
|            (this.drilldownFilters && this.drilldownFilters.length > 0) ||  | ||||
|            this.hasActiveLayerFilters(); | ||||
|   } | ||||
| 
 | ||||
|   // Check if there are active layer filters for current drilldown level
 | ||||
|   hasActiveLayerFilters(): boolean { | ||||
|     if (this.currentDrilldownLevel > 1 && this.drilldownLayers && this.drilldownLayers.length > 0) { | ||||
|       const layerIndex = this.currentDrilldownLevel - 2; // -2 because level 1 is base drilldown
 | ||||
|       return layerIndex < this.drilldownLayers.length &&  | ||||
|              this.drilldownLayers[layerIndex].filters &&  | ||||
|              this.drilldownLayers[layerIndex].filters.length > 0; | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   // Get active layer filters for current drilldown level
 | ||||
|   getActiveLayerFilters(): any[] { | ||||
|     if (this.currentDrilldownLevel > 1 && this.drilldownLayers && this.drilldownLayers.length > 0) { | ||||
|       const layerIndex = this.currentDrilldownLevel - 2; // -2 because level 1 is base drilldown
 | ||||
|       if (layerIndex < this.drilldownLayers.length &&  | ||||
|           this.drilldownLayers[layerIndex].filters) { | ||||
|         return this.drilldownLayers[layerIndex].filters; | ||||
|       } | ||||
|     } | ||||
|     return []; | ||||
|   } | ||||
| 
 | ||||
|   // Get filter options for dropdown/multiselect filters
 | ||||
|   getFilterOptions(filter: any): string[] { | ||||
|     if (filter.options) { | ||||
|       if (Array.isArray(filter.options)) { | ||||
|         return filter.options; | ||||
|       } else if (typeof filter.options === 'string') { | ||||
|         return filter.options.split(',').map(opt => opt.trim()).filter(opt => opt); | ||||
|       } | ||||
|     } | ||||
|     return []; | ||||
|   } | ||||
| 
 | ||||
|   // Check if an option is selected for multiselect filters
 | ||||
|   isOptionSelected(filter: any, option: string): boolean { | ||||
|     if (!filter.value) { | ||||
|       return false; | ||||
|     } | ||||
|      | ||||
|     if (Array.isArray(filter.value)) { | ||||
|       return filter.value.includes(option); | ||||
|     } | ||||
|      | ||||
|     return filter.value === option; | ||||
|   } | ||||
| 
 | ||||
|   // Handle base filter changes
 | ||||
|   onBaseFilterChange(filter: any): void { | ||||
|     console.log('Base filter changed:', filter); | ||||
|     // Refresh data when filter changes
 | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| 
 | ||||
|   // Handle drilldown filter changes
 | ||||
|   onDrilldownFilterChange(filter: any): void { | ||||
|     console.log('Drilldown filter changed:', filter); | ||||
|     // Refresh data when filter changes
 | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| 
 | ||||
|   // Handle layer filter changes
 | ||||
|   onLayerFilterChange(filter: any): void { | ||||
|     console.log('Layer filter changed:', filter); | ||||
|     // Refresh data when filter changes
 | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| 
 | ||||
|   // Handle multiselect changes
 | ||||
|   onMultiSelectChange(filter: any, option: string, event: any): void { | ||||
|     const checked = event.target.checked; | ||||
|      | ||||
|     // Initialize filter.value as array if it's not already
 | ||||
|     if (!Array.isArray(filter.value)) { | ||||
|       filter.value = []; | ||||
|     } | ||||
|      | ||||
|     if (checked) { | ||||
|       // Add option to array if not already present
 | ||||
|       if (!filter.value.includes(option)) { | ||||
|         filter.value.push(option); | ||||
|       } | ||||
|     } else { | ||||
|       // Remove option from array
 | ||||
|       filter.value = filter.value.filter((item: string) => item !== option); | ||||
|     } | ||||
|      | ||||
|     // Refresh data when filter changes
 | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| 
 | ||||
|   // Handle date range changes
 | ||||
|   onDateRangeChange(filter: any, dateRange: { start: string | null, end: string | null }): void { | ||||
|     filter.value = dateRange; | ||||
|     // Refresh data when filter changes
 | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| 
 | ||||
|   // Handle toggle changes
 | ||||
|   onToggleChange(filter: any, checked: boolean): void { | ||||
|     filter.value = checked; | ||||
|     // Refresh data when filter changes
 | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| 
 | ||||
|   // Clear all filters
 | ||||
|   clearAllFilters(): void { | ||||
|     // Clear base filters
 | ||||
|     if (this.baseFilters) { | ||||
|       this.baseFilters.forEach(filter => { | ||||
|         if (filter.type === 'multiselect') { | ||||
|           filter.value = []; | ||||
|         } else if (filter.type === 'date-range') { | ||||
|           filter.value = { start: null, end: null }; | ||||
|         } else if (filter.type === 'toggle') { | ||||
|           filter.value = false; | ||||
|         } else { | ||||
|           filter.value = ''; | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     // Clear drilldown filters
 | ||||
|     if (this.drilldownFilters) { | ||||
|       this.drilldownFilters.forEach(filter => { | ||||
|         if (filter.type === 'multiselect') { | ||||
|           filter.value = []; | ||||
|         } else if (filter.type === 'date-range') { | ||||
|           filter.value = { start: null, end: null }; | ||||
|         } else if (filter.type === 'toggle') { | ||||
|           filter.value = false; | ||||
|         } else { | ||||
|           filter.value = ''; | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     // Clear layer filters
 | ||||
|     if (this.drilldownLayers) { | ||||
|       this.drilldownLayers.forEach(layer => { | ||||
|         if (layer.filters) { | ||||
|           layer.filters.forEach((filter: any) => { | ||||
|             if (filter.type === 'multiselect') { | ||||
|               filter.value = []; | ||||
|             } else if (filter.type === 'date-range') { | ||||
|               filter.value = { start: null, end: null }; | ||||
|             } else if (filter.type === 'toggle') { | ||||
|               filter.value = false; | ||||
|             } else { | ||||
|               filter.value = ''; | ||||
|             } | ||||
|           }); | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     // Refresh data
 | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| 
 | ||||
|   ngOnDestroy() { | ||||
|     // Unsubscribe from all subscriptions to prevent memory leaks
 | ||||
|     console.log('GridViewComponent ngOnDestroy called, unsubscribing from', this.subscriptions.length, 'subscriptions'); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user