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