grid view
This commit is contained in:
		
							parent
							
								
									e6779e8f34
								
							
						
					
					
						commit
						4f82ae8698
					
				| @ -1,5 +1,223 @@ | |||||||
| <div style="display: block;"> | <div style="display: block;"> | ||||||
|   <div class="dg-wrapper"> |   <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-row"> | ||||||
|       <div class="clr-col-8"> |       <div class="clr-col-8"> | ||||||
|         <h3>{{charttitle || 'Data Grid'}}</h3> |         <h3>{{charttitle || 'Data Grid'}}</h3> | ||||||
|  | |||||||
| @ -1,28 +1,132 @@ | |||||||
| // Add styles for drilldown navigation | .filter-section { | ||||||
| .alert-info { |   margin-bottom: 20px; | ||||||
|   background-color: #dcedf7; |   padding: 15px; | ||||||
|   border-color: #a3d4f5; |   border: 1px solid #ddd; | ||||||
|   color: #21333b; |   border-radius: 4px; | ||||||
|  |   background-color: #f9f9f9; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .alert-info .alert-icon { | .filter-group { | ||||||
|   color: #0072a3; |   margin-bottom: 15px; | ||||||
|  |    | ||||||
|  |   h4 { | ||||||
|  |     margin-top: 0; | ||||||
|  |     margin-bottom: 10px; | ||||||
|  |     color: #333; | ||||||
|  |     font-weight: 600; | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .btn-link { | .filter-controls { | ||||||
|   color: #0072a3; |   display: flex; | ||||||
|   text-decoration: none; |   flex-wrap: wrap; | ||||||
|  |   gap: 15px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .btn-link:hover { | .filter-item { | ||||||
|   color: #00567a; |   flex: 1 1 300px; | ||||||
|   text-decoration: underline; |   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 { | .dg-wrapper { | ||||||
|   padding: 12px; |   padding: 15px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .clr-row { | clr-datagrid { | ||||||
|   margin-bottom: 12px; |   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
 |   // Add subscriptions to unsubscribe on destroy
 | ||||||
|   private subscriptions: Subscription[] = []; |   private subscriptions: Subscription[] = []; | ||||||
| 
 | 
 | ||||||
|  |   // Add a flag to track if filters have been initialized
 | ||||||
|  |   private filtersInitialized: boolean = false; | ||||||
|  | 
 | ||||||
|   constructor( |   constructor( | ||||||
|     private mainservice: UsergrpmaintainceService, |     private mainservice: UsergrpmaintainceService, | ||||||
|     private dashboardService: Dashboard3Service, |     private dashboardService: Dashboard3Service, | ||||||
| @ -102,6 +105,12 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|     const drilldownYAxisChanged = changes.drilldownYAxis && !changes.drilldownYAxis.firstChange; |     const drilldownYAxisChanged = changes.drilldownYAxis && !changes.drilldownYAxis.firstChange; | ||||||
|     const drilldownLayersChanged = changes.drilldownLayers && !changes.drilldownLayers.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
 |     // Respond to input changes
 | ||||||
|     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || |     if (!this.isFetchingData && (xAxisChanged || yAxisChanged || tableChanged || connectionChanged || baseFiltersChanged || | ||||||
|       drilldownEnabledChanged || drilldownApiUrlChanged || drilldownXAxisChanged || drilldownYAxisChanged || |       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
 |   // Dynamic headers for the grid
 | ||||||
| 
 | 
 | ||||||
|   fetchGridData(): void { |   fetchGridData(): void { | ||||||
| @ -628,6 +715,174 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|       .replace(/^./, str => str.toUpperCase()); |       .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() { |   ngOnDestroy() { | ||||||
|     // Unsubscribe from all subscriptions to prevent memory leaks
 |     // Unsubscribe from all subscriptions to prevent memory leaks
 | ||||||
|     console.log('GridViewComponent ngOnDestroy called, unsubscribing from', this.subscriptions.length, 'subscriptions'); |     console.log('GridViewComponent ngOnDestroy called, unsubscribing from', this.subscriptions.length, 'subscriptions'); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user