grid view
This commit is contained in:
		
							parent
							
								
									4f82ae8698
								
							
						
					
					
						commit
						ced99e0940
					
				| @ -28,16 +28,25 @@ | ||||
|               </select> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Multi-Select Filter --> | ||||
|             <!-- Multi-Select Filter - Updated to show key first, then dropdown on click --> | ||||
|             <div *ngIf="filter.type === 'multiselect'" class="filter-input multiselect-container"> | ||||
|               <div class="multiselect-display" (click)="toggleMultiselect(filter, 'base')"> | ||||
|                 <span class="multiselect-label">{{ filter.field }}</span> | ||||
|                 <span class="multiselect-value" *ngIf="getSelectedOptionsCount(filter) > 0"> | ||||
|                   ({{ getSelectedOptionsCount(filter) }} selected) | ||||
|                 </span> | ||||
|                 <clr-icon shape="caret down" class="dropdown-icon"></clr-icon> | ||||
|               </div> | ||||
|               <div class="multiselect-dropdown" *ngIf="isMultiselectOpen(filter, 'base')"> | ||||
|                 <div class="checkbox-group"> | ||||
|                 <div *ngFor="let option of getFilterOptions(filter)" class="checkbox-item"> | ||||
|                   <div *ngFor="let option of getFilterOptions(filter); let i = index" class="checkbox-item"> | ||||
|                     <input type="checkbox"  | ||||
|                            [checked]="isOptionSelected(filter, option)"  | ||||
|                            (change)="onMultiSelectChange(filter, option, $event)" | ||||
|                          [id]="'base-' + filter.field + '-' + option"  | ||||
|                            [id]="'base-' + filter.field + '-' + i"  | ||||
|                            class="clr-checkbox"> | ||||
|                   <label [for]="'base-' + filter.field + '-' + option" class="checkbox-label">{{ option }}</label> | ||||
|                     <label [for]="'base-' + filter.field + '-' + i" class="checkbox-label">{{ option }}</label> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
| @ -98,16 +107,25 @@ | ||||
|               </select> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Multi-Select Filter --> | ||||
|             <!-- Multi-Select Filter - Updated to show key first, then dropdown on click --> | ||||
|             <div *ngIf="filter.type === 'multiselect'" class="filter-input multiselect-container"> | ||||
|               <div class="multiselect-display" (click)="toggleMultiselect(filter, 'drilldown')"> | ||||
|                 <span class="multiselect-label">{{ filter.field }}</span> | ||||
|                 <span class="multiselect-value" *ngIf="getSelectedOptionsCount(filter) > 0"> | ||||
|                   ({{ getSelectedOptionsCount(filter) }} selected) | ||||
|                 </span> | ||||
|                 <clr-icon shape="caret down" class="dropdown-icon"></clr-icon> | ||||
|               </div> | ||||
|               <div class="multiselect-dropdown" *ngIf="isMultiselectOpen(filter, 'drilldown')"> | ||||
|                 <div class="checkbox-group"> | ||||
|                 <div *ngFor="let option of getFilterOptions(filter)" class="checkbox-item"> | ||||
|                   <div *ngFor="let option of getFilterOptions(filter); let i = index" class="checkbox-item"> | ||||
|                     <input type="checkbox"  | ||||
|                            [checked]="isOptionSelected(filter, option)"  | ||||
|                            (change)="onMultiSelectChange(filter, option, $event)" | ||||
|                          [id]="'drilldown-' + filter.field + '-' + option"  | ||||
|                            [id]="'drilldown-' + filter.field + '-' + i"  | ||||
|                            class="clr-checkbox"> | ||||
|                   <label [for]="'drilldown-' + filter.field + '-' + option" class="checkbox-label">{{ option }}</label> | ||||
|                     <label [for]="'drilldown-' + filter.field + '-' + i" class="checkbox-label">{{ option }}</label> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
| @ -168,16 +186,25 @@ | ||||
|               </select> | ||||
|             </div> | ||||
|              | ||||
|             <!-- Multi-Select Filter --> | ||||
|             <!-- Multi-Select Filter - Updated to show key first, then dropdown on click --> | ||||
|             <div *ngIf="filter.type === 'multiselect'" class="filter-input multiselect-container"> | ||||
|               <div class="multiselect-display" (click)="toggleMultiselect(filter, 'layer')"> | ||||
|                 <span class="multiselect-label">{{ filter.field }}</span> | ||||
|                 <span class="multiselect-value" *ngIf="getSelectedOptionsCount(filter) > 0"> | ||||
|                   ({{ getSelectedOptionsCount(filter) }} selected) | ||||
|                 </span> | ||||
|                 <clr-icon shape="caret down" class="dropdown-icon"></clr-icon> | ||||
|               </div> | ||||
|               <div class="multiselect-dropdown" *ngIf="isMultiselectOpen(filter, 'layer')"> | ||||
|                 <div class="checkbox-group"> | ||||
|                 <div *ngFor="let option of getFilterOptions(filter)" class="checkbox-item"> | ||||
|                   <div *ngFor="let option of getFilterOptions(filter); let i = index" class="checkbox-item"> | ||||
|                     <input type="checkbox"  | ||||
|                            [checked]="isOptionSelected(filter, option)"  | ||||
|                            (change)="onMultiSelectChange(filter, option, $event)" | ||||
|                          [id]="'layer-' + filter.field + '-' + option"  | ||||
|                            [id]="'layer-' + filter.field + '-' + i"  | ||||
|                            class="clr-checkbox"> | ||||
|                   <label [for]="'layer-' + filter.field + '-' + option" class="checkbox-label">{{ option }}</label> | ||||
|                     <label [for]="'layer-' + filter.field + '-' + i" class="checkbox-label">{{ option }}</label> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
| @ -58,16 +58,63 @@ | ||||
| } | ||||
| 
 | ||||
| .multiselect-container { | ||||
|   .checkbox-group { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     gap: 5px; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .multiselect-display { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: space-between; | ||||
|   padding: 6px 12px; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 4px; | ||||
|   background: white; | ||||
|   cursor: pointer; | ||||
|   min-height: 34px; | ||||
|    | ||||
|   .multiselect-label { | ||||
|     flex: 1; | ||||
|     font-size: 14px; | ||||
|   } | ||||
|    | ||||
|   .multiselect-value { | ||||
|     color: #666; | ||||
|     font-size: 12px; | ||||
|     margin-right: 8px; | ||||
|   } | ||||
|    | ||||
|   .dropdown-icon { | ||||
|     flex-shrink: 0; | ||||
|     transition: transform 0.2s ease; | ||||
|   } | ||||
|    | ||||
|   &:hover { | ||||
|     border-color: #999; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .multiselect-dropdown { | ||||
|   position: absolute; | ||||
|   top: 100%; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   z-index: 1000; | ||||
|   background: white; | ||||
|   border: 1px solid #ccc; | ||||
|   border-top: none; | ||||
|   border-radius: 0 0 4px 4px; | ||||
|   box-shadow: 0 2px 4px rgba(0,0,0,0.1); | ||||
|   max-height: 200px; | ||||
|   overflow-y: auto; | ||||
|    | ||||
|   .checkbox-group { | ||||
|     padding: 8px; | ||||
|      | ||||
|     .checkbox-item { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       gap: 8px; | ||||
|       padding: 4px 0; | ||||
|        | ||||
|       .checkbox-label { | ||||
|         margin: 0; | ||||
| @ -76,6 +123,7 @@ | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .date-range { | ||||
|   .date-input-group { | ||||
|  | ||||
| @ -69,6 +69,12 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | ||||
|   // Add a flag to track if filters have been initialized
 | ||||
|   private filtersInitialized: boolean = false; | ||||
| 
 | ||||
|   // Add properties to track open multiselect dropdowns
 | ||||
|   private openMultiselects: Map<string, string> = new Map(); // Map of filterId -> context
 | ||||
| 
 | ||||
|   // Add property to track document click handler
 | ||||
|   private documentClickHandler: ((event: MouseEvent) => void) | null = null; | ||||
| 
 | ||||
|   constructor( | ||||
|     private mainservice: UsergrpmaintainceService, | ||||
|     private dashboardService: Dashboard3Service, | ||||
| @ -828,6 +834,67 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| 
 | ||||
|   // Toggle multiselect dropdown visibility
 | ||||
|   toggleMultiselect(filter: any, context: string): void { | ||||
|     const filterId = `${context}-${filter.field}`; | ||||
|     if (this.isMultiselectOpen(filter, context)) { | ||||
|       this.openMultiselects.delete(filterId); | ||||
|     } else { | ||||
|       // Close all other multiselects first
 | ||||
|       this.openMultiselects.clear(); | ||||
|       this.openMultiselects.set(filterId, context); | ||||
|        | ||||
|       // Add document click handler to close dropdown when clicking outside
 | ||||
|       this.addDocumentClickHandler(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Add document click handler to close dropdowns when clicking outside
 | ||||
|   private addDocumentClickHandler(): void { | ||||
|     if (!this.documentClickHandler) { | ||||
|       this.documentClickHandler = (event: MouseEvent) => { | ||||
|         const target = event.target as HTMLElement; | ||||
|         // Check if click is outside any multiselect dropdown
 | ||||
|         if (!target.closest('.multiselect-container')) { | ||||
|           this.openMultiselects.clear(); | ||||
|           this.removeDocumentClickHandler(); | ||||
|         } | ||||
|       }; | ||||
|        | ||||
|       // Use setTimeout to ensure the click event that opened the dropdown doesn't immediately close it
 | ||||
|       setTimeout(() => { | ||||
|         document.addEventListener('click', this.documentClickHandler!); | ||||
|       }, 0); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Remove document click handler
 | ||||
|   private removeDocumentClickHandler(): void { | ||||
|     if (this.documentClickHandler) { | ||||
|       document.removeEventListener('click', this.documentClickHandler); | ||||
|       this.documentClickHandler = null; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Check if multiselect dropdown is open
 | ||||
|   isMultiselectOpen(filter: any, context: string): boolean { | ||||
|     const filterId = `${context}-${filter.field}`; | ||||
|     return this.openMultiselects.has(filterId); | ||||
|   } | ||||
| 
 | ||||
|   // Get count of selected options for a multiselect filter
 | ||||
|   getSelectedOptionsCount(filter: any): number { | ||||
|     if (!filter.value) { | ||||
|       return 0; | ||||
|     } | ||||
|      | ||||
|     if (Array.isArray(filter.value)) { | ||||
|       return filter.value.length; | ||||
|     } | ||||
|      | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   // Clear all filters
 | ||||
|   clearAllFilters(): void { | ||||
|     // Clear base filters
 | ||||
| @ -879,6 +946,9 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     // Close all multiselect dropdowns
 | ||||
|     this.openMultiselects.clear(); | ||||
|      | ||||
|     // Refresh data
 | ||||
|     this.fetchGridData(); | ||||
|   } | ||||
| @ -899,6 +969,12 @@ export class GridViewComponent implements OnInit, OnChanges, OnDestroy { | ||||
|     this.drilldownStack = []; | ||||
|     this.originalGridData = []; | ||||
| 
 | ||||
|     // Clear multiselect tracking
 | ||||
|     this.openMultiselects.clear(); | ||||
|      | ||||
|     // Remove document click handler
 | ||||
|     this.removeDocumentClickHandler(); | ||||
|      | ||||
|     console.log('GridViewComponent destroyed and cleaned up'); | ||||
|   } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user