grid view
This commit is contained in:
@@ -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');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user