This commit is contained in:
string 2025-10-25 20:15:06 +05:30
parent 8266bfdc01
commit 98e0908920
3 changed files with 281 additions and 178 deletions

View File

@ -93,72 +93,88 @@
<h3 class="modal-title">Configure Chart</h3>
<div class="modal-body" *ngIf="selectedItem">
<form [formGroup]="configForm" class="clr-form-horizontal">
<!-- Chart Title -->
<div class="clr-row">
<div class="clr-col-sm-12">
<label for="charttitle">Chart Title</label>
<input id="charttitle" type="text" formControlName="charttitle" class="clr-input">
<div class="clr-col-12">
<clr-input-container>
<label for="charttitle">Chart Title</label>
<input id="charttitle" type="text" formControlName="charttitle" clrInput />
<clr-control-helper>Enter a descriptive title for your chart</clr-control-helper>
</clr-input-container>
</div>
</div>
<!-- Connection Selection Field -->
<div class="clr-row">
<div class="clr-col-sm-12">
<label for="connection">Connection</label>
<select id="connection" formControlName="connection" class="clr-select">
<option value="">Select Connection</option>
<option *ngFor="let conn of sureconnectData" [value]="conn.id">
{{conn.connection_name || conn.id}}
</option>
</select>
<div class="clr-subtext">Select a SureConnect connection to use for this chart</div>
<div class="clr-col-12">
<clr-select-container>
<label for="connection">Connection</label>
<select id="connection" formControlName="connection" clrSelect>
<option value="">Select Connection</option>
<option *ngFor="let conn of sureconnectData" [value]="conn.id">
{{conn.connection_name || conn.id}}
</option>
</select>
<clr-control-helper>Select a SureConnect connection to use for this chart</clr-control-helper>
</clr-select-container>
</div>
</div>
<!-- Chart Options (except for Data Table and Deal Details) -->
<div class="clr-row" *ngIf="selectedItem?.name !== 'Data Table' && selectedItem?.name !== 'Deal Details'">
<div class="clr-col-sm-12">
<div class="clr-form-control" style="margin-top: 5px;margin-bottom: 10px;">
<div class="clr-control-container">
<div class="clr-checkbox-wrapper">
<input type="checkbox" id="chartlegend" formControlName="chartlegend" class="clr-checkbox" />
<label for="chartlegend" class="clr-control-label">Show Chart Legend</label>
</div>
<div class="clr-checkbox-wrapper">
<input type="checkbox" id="showlabel" formControlName="showlabel" class="clr-checkbox" />
<label for="showlabel" class="clr-control-label">Show Chart Label</label>
</div>
<div class="clr-col-12">
<div class="clr-form-control clr-row">
<div class="clr-col-12">
<clr-checkbox-container>
<clr-checkbox-wrapper>
<input type="checkbox" id="chartlegend" formControlName="chartlegend" clrCheckbox />
<label for="chartlegend">Show Chart Legend</label>
</clr-checkbox-wrapper>
<clr-checkbox-wrapper>
<input type="checkbox" id="showlabel" formControlName="showlabel" clrCheckbox />
<label for="showlabel">Show Chart Label</label>
</clr-checkbox-wrapper>
</clr-checkbox-container>
</div>
</div>
</div>
</div>
<!-- API URL -->
<div class="clr-row">
<div class="clr-col-sm-12">
<label for="table">Api Url</label>
<div>
<input type="text" id="table" formControlName="table" class="clr-input" style="width:90%">&nbsp;
<span>
<button class="btn btn-icon btn-primary" style="margin: 0px;" (click)="getColumns(configForm.value.connection, configForm.value.table)">
<clr-icon shape="redo"></clr-icon>
<div class="clr-col-12">
<clr-input-container>
<label for="table">API URL</label>
<div class="clr-input-group">
<input type="text" id="table" formControlName="table" clrInput />
<button class="btn btn-icon btn-primary" (click)="getColumns(configForm.value.connection, configForm.value.table)" type="button">
<clr-icon shape="refresh"></clr-icon>
</button>
</span>
</div>
</div>
<clr-control-helper>Enter the API endpoint for your data source</clr-control-helper>
</clr-input-container>
</div>
</div>
<!-- X-Axis (except for Data Table and Deal Details) -->
<div class="clr-row" *ngIf="selectedItem?.name !== 'Data Table' && selectedItem?.name !== 'Deal Details'">
<div class="clr-col-sm-12">
<label for="xAxis">X-Axis</label>
<select id="xAxis" formControlName="xAxis">
<option value="null">choose Column</option>
<option *ngFor="let data of columnData" [value]="data">{{data}}</option>
</select>
<div class="clr-col-12">
<clr-select-container>
<label for="xAxis">X-Axis</label>
<select id="xAxis" formControlName="xAxis" clrSelect>
<option value="">Select Column</option>
<option *ngFor="let data of columnData" [value]="data">{{data}}</option>
</select>
<clr-control-helper>Select the column to use for the X-axis</clr-control-helper>
</clr-select-container>
</div>
</div>
<!-- Y-Axis (except for Data Table and Deal Details) -->
<div class="clr-row" *ngIf="selectedItem?.name !== 'Data Table' && selectedItem?.name !== 'Deal Details'">
<div class="clr-col-sm-12">
<label for="yAxis">Y-Axis (Numeric)</label>
<clr-combobox-container style="margin-top: 10px !important;">
<div class="clr-col-12">
<clr-combobox-container>
<label for="yAxis">Y-Axis (Numeric)</label>
<clr-combobox id="yAxis" formControlName="yAxis" clrMulti="true" required>
<ng-container *clrOptionSelected="let selected">
{{selected}}
@ -169,43 +185,48 @@
</clr-option>
</clr-options>
</clr-combobox>
<clr-control-helper>Select one or more columns for the Y-axis</clr-control-helper>
</clr-combobox-container>
</div>
</div>
<!-- Base API Filters -->
<div class="clr-row" style="margin-top: 15px;">
<div class="clr-col-sm-12">
<h5>Base API Filters</h5>
<!-- Base API Filters Section -->
<div class="clr-row section-divider">
<div class="clr-col-12">
<h4>Base API Filters</h4>
<p class="clr-subtext">Configure filters for the main API (applied regardless of drilldown settings)</p>
<!-- Add Base Filter Button -->
<button class="btn btn-sm btn-primary" (click)="addBaseFilter()" style="margin-top: 10px; margin-bottom: 10px;">
<button class="btn btn-sm btn-primary" (click)="addBaseFilter()" type="button">
<clr-icon shape="plus"></clr-icon> Add Filter
</button>
<!-- Base Filter Fields List -->
<div *ngFor="let filter of selectedItem?.baseFilters; let i = index"
style="margin-bottom: 10px; padding: 8px; border: 1px solid #eee; border-radius: 4px; background-color: #f9f9f9;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div *ngFor="let filter of selectedItem?.baseFilters; let i = index" class="filter-item">
<div class="filter-header">
<span>Filter {{i + 1}}</span>
<button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)" type="button">
<clr-icon shape="trash"></clr-icon>
</button>
</div>
<div class="clr-row" style="margin-top: 8px;">
<div class="clr-col-sm-5">
<input type="text" [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}"
class="clr-input" placeholder="Field Name" />
<div class="clr-row filter-content">
<div class="clr-col-5">
<clr-input-container>
<label [attr.for]="'baseFilterField' + i">Field Name</label>
<input type="text" [id]="'baseFilterField' + i" [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}" clrInput />
</clr-input-container>
</div>
<div class="clr-col-sm-5">
<input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"
class="clr-input" placeholder="Filter Value" />
<div class="clr-col-5">
<clr-input-container>
<label [attr.for]="'baseFilterValue' + i">Filter Value</label>
<input type="text" [id]="'baseFilterValue' + i" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}" clrInput />
</clr-input-container>
</div>
<div class="clr-col-sm-2">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)">
<div class="clr-col-2">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)" type="button">
<clr-icon shape="trash"></clr-icon>
</button>
</div>
@ -215,101 +236,114 @@
</div>
<!-- Base Drilldown Configuration Section -->
<div class="clr-row" style="margin-top: 20px; padding-top: 15px; border-top: 1px solid #ddd;">
<div class="clr-col-sm-12">
<div class="clr-row section-divider">
<div class="clr-col-12">
<h4>Base Drilldown Configuration</h4>
<div class="clr-form-control">
<div class="clr-control-container">
<div class="clr-checkbox-wrapper">
<input type="checkbox" id="drilldownEnabled" [(ngModel)]="selectedItem.drilldownEnabled"
[ngModelOptions]="{standalone: true}" class="clr-checkbox" />
<label for="drilldownEnabled" class="clr-control-label">Enable Base Drilldown</label>
</div>
</div>
</div>
<clr-checkbox-container>
<clr-checkbox-wrapper>
<input type="checkbox" id="drilldownEnabled" [(ngModel)]="selectedItem.drilldownEnabled" [ngModelOptions]="{standalone: true}" clrCheckbox />
<label for="drilldownEnabled">Enable Base Drilldown</label>
</clr-checkbox-wrapper>
</clr-checkbox-container>
<p class="clr-subtext">Enable drilldown functionality for this chart</p>
</div>
</div>
<!-- Drilldown API URL -->
<div class="clr-row" *ngIf="selectedItem?.drilldownEnabled">
<div class="clr-col-sm-12">
<label for="drilldownApiUrl">Base Drilldown API URL</label>
<div>
<input type="text" id="drilldownApiUrl" [(ngModel)]="selectedItem.drilldownApiUrl"
[ngModelOptions]="{standalone: true}" class="clr-input" style="width:90%">&nbsp;
<span>
<button class="btn btn-icon btn-primary" style="margin: 0px;"
(click)="refreshDrilldownColumns()" [disabled]="!selectedItem.drilldownApiUrl">
<clr-icon shape="redo"></clr-icon>
<div class="clr-col-12">
<clr-input-container>
<label for="drilldownApiUrl">Base Drilldown API URL</label>
<div class="clr-input-group">
<input type="text" id="drilldownApiUrl" [(ngModel)]="selectedItem.drilldownApiUrl" [ngModelOptions]="{standalone: true}" clrInput />
<button class="btn btn-icon btn-primary" (click)="refreshDrilldownColumns()" [disabled]="!selectedItem.drilldownApiUrl" type="button">
<clr-icon shape="refresh"></clr-icon>
</button>
</span>
</div>
</div>
<clr-control-helper>Enter the API URL for base drilldown data. Use angle brackets for parameters, e.g., http://api.example.com/data/&lt;country&gt;</clr-control-helper>
</clr-input-container>
</div>
</div>
<!-- Drilldown X-Axis -->
<div class="clr-row" *ngIf="selectedItem?.drilldownEnabled">
<div class="clr-col-sm-12">
<label for="drilldownXAxis">Base Drilldown X-Axis</label>
<select id="drilldownXAxis" [(ngModel)]="selectedItem.drilldownXAxis" [ngModelOptions]="{standalone: true}">
<option value="">Select X-Axis Column</option>
<option *ngFor="let column of drilldownColumnData" [value]="column">{{column}}</option>
</select>
<div class="clr-col-12">
<clr-select-container>
<label for="drilldownXAxis">Base Drilldown X-Axis</label>
<select id="drilldownXAxis" [(ngModel)]="selectedItem.drilldownXAxis" [ngModelOptions]="{standalone: true}" clrSelect>
<option value="">Select X-Axis Column</option>
<option *ngFor="let column of drilldownColumnData" [value]="column">{{column}}</option>
</select>
<clr-control-helper>Select the column to use for X-axis in base drilldown view</clr-control-helper>
</clr-select-container>
</div>
</div>
<!-- Drilldown Y-Axis (except for Deal Details) -->
<div class="clr-row" *ngIf="selectedItem?.drilldownEnabled && selectedItem?.name !== 'Deal Details'">
<div class="clr-col-sm-12">
<label for="drilldownYAxis">Base Drilldown Y-Axis</label>
<select id="drilldownYAxis" [(ngModel)]="selectedItem.drilldownYAxis" [ngModelOptions]="{standalone: true}">
<option value="">Select Y-Axis Column</option>
<option *ngFor="let column of drilldownColumnData" [value]="column">{{column}}</option>
</select>
<div class="clr-col-12">
<clr-select-container>
<label for="drilldownYAxis">Base Drilldown Y-Axis</label>
<select id="drilldownYAxis" [(ngModel)]="selectedItem.drilldownYAxis" [ngModelOptions]="{standalone: true}" clrSelect>
<option value="">Select Y-Axis Column</option>
<option *ngFor="let column of drilldownColumnData" [value]="column">{{column}}</option>
</select>
<clr-control-helper>Select the column to use for Y-axis in base drilldown view</clr-control-helper>
</clr-select-container>
</div>
</div>
<!-- Base Drilldown Parameter Configuration -->
<!-- Drilldown Parameter -->
<div class="clr-row" *ngIf="selectedItem?.drilldownEnabled">
<div class="clr-col-sm-12">
<label for="drilldownParameter">Base Drilldown Parameter</label>
<select id="drilldownParameter" [(ngModel)]="selectedItem.drilldownParameter" [ngModelOptions]="{standalone: true}">
<option value="">Select Parameter Column</option>
<option *ngFor="let column of drilldownColumnData" [value]="column">{{column}}</option>
</select>
<div class="clr-col-12">
<clr-select-container>
<label for="drilldownParameter">Base Drilldown Parameter</label>
<select id="drilldownParameter" [(ngModel)]="selectedItem.drilldownParameter" [ngModelOptions]="{standalone: true}" clrSelect>
<option value="">Select Parameter Column</option>
<option *ngFor="let column of drilldownColumnData" [value]="column">{{column}}</option>
</select>
<clr-control-helper>Select the column to use as parameter for URL template replacement in base drilldown</clr-control-helper>
</clr-select-container>
</div>
</div>
<!-- Base Drilldown Filter Configuration -->
<div class="clr-row" *ngIf="selectedItem?.drilldownEnabled" style="margin-top: 15px;">
<div class="clr-col-sm-12">
<div class="clr-row section-divider" *ngIf="selectedItem?.drilldownEnabled">
<div class="clr-col-12">
<h5>Base Drilldown Filters</h5>
<p class="clr-subtext">Configure filters for the base drilldown level</p>
<!-- Add Drilldown Filter Button -->
<button class="btn btn-sm btn-primary" (click)="addDrilldownFilter()" style="margin-top: 10px; margin-bottom: 10px;">
<button class="btn btn-sm btn-primary" (click)="addDrilldownFilter()" type="button">
<clr-icon shape="plus"></clr-icon> Add Filter
</button>
<!-- Drilldown Filter Fields List -->
<div *ngFor="let filter of selectedItem?.drilldownFilters; let i = index"
style="margin-bottom: 10px; padding: 8px; border: 1px solid #eee; border-radius: 4px; background-color: #f9f9f9;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div *ngFor="let filter of selectedItem?.drilldownFilters; let i = index" class="filter-item">
<div class="filter-header">
<span>Filter {{i + 1}}</span>
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownFilter(i)">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownFilter(i)" type="button">
<clr-icon shape="trash"></clr-icon>
</button>
</div>
<div class="clr-row" style="margin-top: 8px;">
<div class="clr-col-sm-5">
<input type="text" [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}"
class="clr-input" placeholder="Field Name" />
<div class="clr-row filter-content">
<div class="clr-col-5">
<clr-input-container>
<label [attr.for]="'drilldownFilterField' + i">Field Name</label>
<input type="text" [id]="'drilldownFilterField' + i" [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}" clrInput />
</clr-input-container>
</div>
<div class="clr-col-sm-5">
<input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"
class="clr-input" placeholder="Filter Value" />
<div class="clr-col-5">
<clr-input-container>
<label [attr.for]="'drilldownFilterValue' + i">Filter Value</label>
<input type="text" [id]="'drilldownFilterValue' + i" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}" clrInput />
</clr-input-container>
</div>
<div class="clr-col-sm-2">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownFilter(i)">
<div class="clr-col-2">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownFilter(i)" type="button">
<clr-icon shape="trash"></clr-icon>
</button>
</div>
@ -319,115 +353,128 @@
</div>
<!-- Multi-Layer Drilldown Configurations -->
<div class="clr-row" *ngIf="selectedItem?.drilldownEnabled" style="margin-top: 20px; padding-top: 15px; border-top: 1px solid #ddd;">
<div class="clr-col-sm-12">
<div class="clr-row section-divider" *ngIf="selectedItem?.drilldownEnabled">
<div class="clr-col-12">
<h4>Multi-Layer Drilldown Configurations</h4>
<button class="btn btn-sm btn-primary" (click)="addDrilldownLayer()">
<button class="btn btn-sm btn-primary" (click)="addDrilldownLayer()" type="button">
<clr-icon shape="plus"></clr-icon> Add Drilldown Layer
</button>
<p class="clr-subtext">Add additional drilldown layers for multi-level navigation</p>
</div>
</div>
<!-- Dynamic Drilldown Layers -->
<div class="clr-row" *ngFor="let layer of selectedItem?.drilldownLayers; let i = index">
<div class="clr-col-sm-12" style="margin-top: 15px; padding: 10px; border: 1px solid #eee; border-radius: 4px;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div class="clr-col-12 drilldown-layer">
<div class="layer-header">
<h5>Drilldown Layer {{i + 1}}</h5>
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownLayer(i)">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownLayer(i)" type="button">
<clr-icon shape="trash"></clr-icon>
</button>
</div>
<div class="clr-form-control">
<div class="clr-control-container">
<div class="clr-checkbox-wrapper">
<input type="checkbox" [id]="'layerEnabled' + i" [(ngModel)]="layer.enabled"
[ngModelOptions]="{standalone: true}" class="clr-checkbox" />
<label [for]="'layerEnabled' + i" class="clr-control-label">Enable Layer {{i + 1}} Drilldown</label>
</div>
</div>
</div>
<clr-checkbox-container>
<clr-checkbox-wrapper>
<input type="checkbox" [id]="'layerEnabled' + i" [(ngModel)]="layer.enabled" [ngModelOptions]="{standalone: true}" clrCheckbox />
<label [for]="'layerEnabled' + i">Enable Layer {{i + 1}} Drilldown</label>
</clr-checkbox-wrapper>
</clr-checkbox-container>
<!-- Layer API URL -->
<div class="clr-row">
<div class="clr-col-sm-12">
<label [for]="'layerApiUrl' + i">Layer {{i + 1}} API URL</label>
<div>
<input type="text" [id]="'layerApiUrl' + i" class="clr-input"
[(ngModel)]="layer.apiUrl" style="width:90%" [ngModelOptions]="{standalone: true}">&nbsp;
<span>
<button class="btn btn-icon btn-primary" style="margin: 0px;"
(click)="refreshDrilldownLayerColumns(i)" [disabled]="!layer.apiUrl">
<clr-icon shape="redo"></clr-icon>
<div class="clr-col-12">
<clr-input-container>
<label [for]="'layerApiUrl' + i">Layer {{i + 1}} API URL</label>
<div class="clr-input-group">
<input type="text" [id]="'layerApiUrl' + i" [(ngModel)]="layer.apiUrl" clrInput [ngModelOptions]="{standalone: true}" />
<button class="btn btn-icon btn-primary" (click)="refreshDrilldownLayerColumns(i)" [disabled]="!layer.apiUrl" type="button">
<clr-icon shape="refresh"></clr-icon>
</button>
</span>
</div>
</div>
<clr-control-helper>Enter the API URL for layer {{i + 1}} drilldown data. Use angle brackets for parameters, e.g., http://api.example.com/data/&lt;state&gt;</clr-control-helper>
</clr-input-container>
</div>
</div>
<!-- Layer X-Axis -->
<div class="clr-row">
<div class="clr-col-sm-12">
<label [for]="'layerXAxis' + i">Layer {{i + 1}} X-Axis</label>
<select [id]="'layerXAxis' + i" [(ngModel)]="layer.xAxis" [ngModelOptions]="{standalone: true}">
<option value="">Select X-Axis Column</option>
<option *ngFor="let column of layerColumnData[i] || []" [value]="column">{{column}}</option>
</select>
<div class="clr-col-12">
<clr-select-container>
<label [for]="'layerXAxis' + i">Layer {{i + 1}} X-Axis</label>
<select [id]="'layerXAxis' + i" [(ngModel)]="layer.xAxis" [ngModelOptions]="{standalone: true}" clrSelect>
<option value="">Select X-Axis Column</option>
<option *ngFor="let column of layerColumnData[i] || []" [value]="column">{{column}}</option>
</select>
<clr-control-helper>Select the column to use for X-axis in layer {{i + 1}} drilldown view</clr-control-helper>
</clr-select-container>
</div>
</div>
<!-- Layer Y-Axis (except for Deal Details) -->
<div class="clr-row" *ngIf="selectedItem?.name !== 'Deal Details'">
<div class="clr-col-sm-12">
<label [for]="'layerYAxis' + i">Layer {{i + 1}} Y-Axis</label>
<select [id]="'layerYAxis' + i" [(ngModel)]="layer.yAxis" [ngModelOptions]="{standalone: true}">
<option value="">Select Y-Axis Column</option>
<option *ngFor="let column of layerColumnData[i] || []" [value]="column">{{column}}</option>
</select>
<div class="clr-col-12">
<clr-select-container>
<label [for]="'layerYAxis' + i">Layer {{i + 1}} Y-Axis</label>
<select [id]="'layerYAxis' + i" [(ngModel)]="layer.yAxis" [ngModelOptions]="{standalone: true}" clrSelect>
<option value="">Select Y-Axis Column</option>
<option *ngFor="let column of layerColumnData[i] || []" [value]="column">{{column}}</option>
</select>
<clr-control-helper>Select the column to use for Y-axis in layer {{i + 1}} drilldown view</clr-control-helper>
</clr-select-container>
</div>
</div>
<!-- Parameter Selection for Drilldown Layer -->
<div class="clr-row">
<div class="clr-col-sm-12">
<label [for]="'layerParameter' + i">Layer {{i + 1}} Parameter</label>
<select [id]="'layerParameter' + i" [(ngModel)]="layer.parameter" [ngModelOptions]="{standalone: true}">
<option value="">Select Parameter Column</option>
<option *ngFor="let column of layerColumnData[i] || []" [value]="column">{{column}}</option>
</select>
<div class="clr-col-12">
<clr-select-container>
<label [for]="'layerParameter' + i">Layer {{i + 1}} Parameter</label>
<select [id]="'layerParameter' + i" [(ngModel)]="layer.parameter" [ngModelOptions]="{standalone: true}" clrSelect>
<option value="">Select Parameter Column</option>
<option *ngFor="let column of layerColumnData[i] || []" [value]="column">{{column}}</option>
</select>
<clr-control-helper>Select the column to use as parameter for URL template replacement in layer {{i + 1}} drilldown</clr-control-helper>
</clr-select-container>
</div>
</div>
<!-- Layer Filter Configuration -->
<div class="clr-row" style="margin-top: 15px;">
<div class="clr-col-sm-12">
<div class="clr-row section-divider">
<div class="clr-col-12">
<h5>Layer {{i + 1}} Filters</h5>
<p class="clr-subtext">Configure filters for this drilldown layer</p>
<!-- Add Layer Filter Button -->
<button class="btn btn-sm btn-primary" (click)="addLayerFilter(i)" style="margin-top: 10px; margin-bottom: 10px;">
<button class="btn btn-sm btn-primary" (click)="addLayerFilter(i)" type="button">
<clr-icon shape="plus"></clr-icon> Add Filter
</button>
<!-- Layer Filter Fields List -->
<div *ngFor="let filter of layer.filters; let j = index"
style="margin-bottom: 10px; padding: 8px; border: 1px solid #eee; border-radius: 4px; background-color: #f9f9f9;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div *ngFor="let filter of layer.filters; let j = index" class="filter-item">
<div class="filter-header">
<span>Filter {{j + 1}}</span>
<button class="btn btn-icon btn-danger btn-sm" (click)="removeLayerFilter(i, j)">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeLayerFilter(i, j)" type="button">
<clr-icon shape="trash"></clr-icon>
</button>
</div>
<div class="clr-row" style="margin-top: 8px;">
<div class="clr-col-sm-5">
<input type="text" [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}"
class="clr-input" placeholder="Field Name" />
<div class="clr-row filter-content">
<div class="clr-col-5">
<clr-input-container>
<label [attr.for]="'layerFilterField' + i + '_' + j">Field Name</label>
<input type="text" [id]="'layerFilterField' + i + '_' + j" [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}" clrInput />
</clr-input-container>
</div>
<div class="clr-col-sm-5">
<input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"
class="clr-input" placeholder="Filter Value" />
<div class="clr-col-5">
<clr-input-container>
<label [attr.for]="'layerFilterValue' + i + '_' + j">Filter Value</label>
<input type="text" [id]="'layerFilterValue' + i + '_' + j" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}" clrInput />
</clr-input-container>
</div>
<div class="clr-col-sm-2">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeLayerFilter(i, j)">
<div class="clr-col-2">
<button class="btn btn-icon btn-danger btn-sm" (click)="removeLayerFilter(i, j)" type="button">
<clr-icon shape="trash"></clr-icon>
</button>
</div>

View File

@ -146,6 +146,60 @@ gridster-item {
overflow: hidden;
}
/* Configuration Modal Styles */
.section-divider {
margin-top: 20px;
padding-top: 15px;
border-top: 1px solid #eee;
}
.section-divider:first-child {
border-top: none;
padding-top: 0;
margin-top: 0;
}
.filter-item {
margin-bottom: 15px;
padding: 12px;
border: 1px solid #e9ecef;
border-radius: 4px;
background-color: #f8f9fa;
}
.filter-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.filter-content {
margin-top: 10px;
}
.drilldown-layer {
margin-top: 20px;
padding: 15px;
border: 1px solid #dee2e6;
border-radius: 4px;
background-color: #ffffff;
}
.layer-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.layer-header h5 {
margin: 0;
color: #495057;
}
/* Responsive design */
@media (max-width: 768px) {
.dashboard-container {
@ -159,4 +213,8 @@ gridster-item {
.kpi-section {
flex-direction: column;
}
.filter-item .clr-row > div {
margin-bottom: 10px;
}
}

View File

@ -477,8 +477,6 @@ export class ShieldDashboardComponent implements OnInit {
}
}
// Add base filter
addBaseFilter() {
if (this.selectedItem) {