dashboard
This commit is contained in:
@@ -23,18 +23,6 @@
|
||||
|
||||
<!-- Main Dashboard Content -->
|
||||
<div class="main-content">
|
||||
<!-- KPI Metrics -->
|
||||
<!-- <div class="kpi-section">
|
||||
<div class="kpi-card total-leads">
|
||||
<div class="kpi-title">Total Leads</div>
|
||||
<div class="kpi-value">1,248</div>
|
||||
</div>
|
||||
<div class="kpi-card total-deals">
|
||||
<div class="kpi-title">Total Deals</div>
|
||||
<div class="kpi-value">842</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Deleted Items Section -->
|
||||
<div class="deleted-items-section" *ngIf="deletedItems.length > 0">
|
||||
<h3>Deleted Items</h3>
|
||||
@@ -52,9 +40,6 @@
|
||||
</div>
|
||||
|
||||
<!-- Dashboard Grid with Drag and Drop -->
|
||||
<!-- <div class="drop-zone-indicator" *ngIf="dashboard.length === 0">
|
||||
<p>Drag components here from the sidebar</p>
|
||||
</div> -->
|
||||
<gridster [options]="options" (drop)="onDrop($event)" style="background-color: transparent; min-height: 500px;">
|
||||
<gridster-item [item]="item" *ngFor="let item of dashboard">
|
||||
<!-- Remove Button -->
|
||||
@@ -62,6 +47,11 @@
|
||||
<clr-icon shape="trash"></clr-icon>
|
||||
</button>
|
||||
|
||||
<!-- Edit Button -->
|
||||
<button class="btn btn-icon" style="margin-top: 10px; float: right;" (click)="editGadget(item)">
|
||||
<clr-icon shape="pencil"></clr-icon>
|
||||
</button>
|
||||
|
||||
<!-- Drag Handle -->
|
||||
<button class="btn btn-icon drag-handler" style="margin-left: 10px; margin-top: 10px;">
|
||||
<clr-icon shape="drag-handle"></clr-icon>
|
||||
@@ -97,3 +87,360 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration Modal -->
|
||||
<clr-modal [(clrModalOpen)]="modeledit" [clrModalStaticBackdrop]="true" clrModalSize="lg">
|
||||
<h3 class="modal-title">Configure Chart</h3>
|
||||
<div class="modal-body" *ngIf="selectedItem">
|
||||
<form [formGroup]="configForm" class="clr-form-horizontal">
|
||||
<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>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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%">
|
||||
<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>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<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;">
|
||||
<clr-combobox id="yAxis" formControlName="yAxis" clrMulti="true" required>
|
||||
<ng-container *clrOptionSelected="let selected">
|
||||
{{selected}}
|
||||
</ng-container>
|
||||
<clr-options>
|
||||
<clr-option *clrOptionItems="let state of columnData" [clrValue]="state">
|
||||
{{state}}
|
||||
</clr-option>
|
||||
</clr-options>
|
||||
</clr-combobox>
|
||||
</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>
|
||||
|
||||
<!-- Add Base Filter Button -->
|
||||
<button class="btn btn-sm btn-primary" (click)="addBaseFilter()" style="margin-top: 10px; margin-bottom: 10px;">
|
||||
<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;">
|
||||
<span>Filter {{i + 1}}</span>
|
||||
<button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)">
|
||||
<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>
|
||||
|
||||
<div class="clr-col-sm-5">
|
||||
<input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"
|
||||
class="clr-input" placeholder="Filter Value" />
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-2">
|
||||
<button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)">
|
||||
<clr-icon shape="trash"></clr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</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">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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%">
|
||||
<span>
|
||||
<button class="btn btn-icon btn-primary" style="margin: 0px;"
|
||||
(click)="refreshDrilldownColumns()" [disabled]="!selectedItem.drilldownApiUrl">
|
||||
<clr-icon shape="redo"></clr-icon>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- Base Drilldown Parameter Configuration -->
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- Base Drilldown Filter Configuration -->
|
||||
<div class="clr-row" *ngIf="selectedItem?.drilldownEnabled" style="margin-top: 15px;">
|
||||
<div class="clr-col-sm-12">
|
||||
<h5>Base Drilldown Filters</h5>
|
||||
|
||||
<!-- Add Drilldown Filter Button -->
|
||||
<button class="btn btn-sm btn-primary" (click)="addDrilldownFilter()" style="margin-top: 10px; margin-bottom: 10px;">
|
||||
<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;">
|
||||
<span>Filter {{i + 1}}</span>
|
||||
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownFilter(i)">
|
||||
<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>
|
||||
|
||||
<div class="clr-col-sm-5">
|
||||
<input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"
|
||||
class="clr-input" placeholder="Filter Value" />
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-2">
|
||||
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownFilter(i)">
|
||||
<clr-icon shape="trash"></clr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</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">
|
||||
<h4>Multi-Layer Drilldown Configurations</h4>
|
||||
<button class="btn btn-sm btn-primary" (click)="addDrilldownLayer()">
|
||||
<clr-icon shape="plus"></clr-icon> Add Drilldown Layer
|
||||
</button>
|
||||
</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;">
|
||||
<h5>Drilldown Layer {{i + 1}}</h5>
|
||||
<button class="btn btn-icon btn-danger btn-sm" (click)="removeDrilldownLayer(i)">
|
||||
<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>
|
||||
|
||||
<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}">
|
||||
<span>
|
||||
<button class="btn btn-icon btn-primary" style="margin: 0px;"
|
||||
(click)="refreshDrilldownLayerColumns(i)" [disabled]="!layer.apiUrl">
|
||||
<clr-icon shape="redo"></clr-icon>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
<!-- Layer Filter Configuration -->
|
||||
<div class="clr-row" style="margin-top: 15px;">
|
||||
<div class="clr-col-sm-12">
|
||||
<h5>Layer {{i + 1}} Filters</h5>
|
||||
|
||||
<!-- Add Layer Filter Button -->
|
||||
<button class="btn btn-sm btn-primary" (click)="addLayerFilter(i)" style="margin-top: 10px; margin-bottom: 10px;">
|
||||
<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;">
|
||||
<span>Filter {{j + 1}}</span>
|
||||
<button class="btn btn-icon btn-danger btn-sm" (click)="removeLayerFilter(i, j)">
|
||||
<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>
|
||||
|
||||
<div class="clr-col-sm-5">
|
||||
<input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"
|
||||
class="clr-input" placeholder="Filter Value" />
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-2">
|
||||
<button class="btn btn-icon btn-danger btn-sm" (click)="removeLayerFilter(i, j)">
|
||||
<clr-icon shape="trash"></clr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline" (click)="cancelConfiguration()">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" (click)="saveConfiguration()">Save</button>
|
||||
</div>
|
||||
</clr-modal>
|
||||
@@ -1,11 +1,31 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { GridsterConfig, GridsterItem } from 'angular-gridster2';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { DatastoreService } from 'src/app/services/fnd/datastore.service';
|
||||
import { AlertsService } from 'src/app/services/fnd/alerts.service';
|
||||
import { SureconnectService } from '../../sureconnect/sureconnect.service';
|
||||
|
||||
interface ShieldDashboardItem extends GridsterItem {
|
||||
chartType: string;
|
||||
name: string;
|
||||
id: number;
|
||||
component?: any;
|
||||
// Configuration properties
|
||||
charttitle?: string;
|
||||
connection?: string;
|
||||
table?: string;
|
||||
xAxis?: string;
|
||||
yAxis?: string[];
|
||||
chartlegend?: boolean;
|
||||
showlabel?: boolean;
|
||||
baseFilters?: any[];
|
||||
drilldownEnabled?: boolean;
|
||||
drilldownApiUrl?: string;
|
||||
drilldownXAxis?: string;
|
||||
drilldownYAxis?: string;
|
||||
drilldownParameter?: string;
|
||||
drilldownFilters?: any[];
|
||||
drilldownLayers?: any[];
|
||||
}
|
||||
|
||||
interface WidgetModel {
|
||||
@@ -22,6 +42,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
options: GridsterConfig;
|
||||
dashboard: Array<ShieldDashboardItem>;
|
||||
|
||||
// Configuration modal
|
||||
configModalOpen = false;
|
||||
modeledit = false; // Add this to match the main dashboard pattern
|
||||
configForm: FormGroup;
|
||||
selectedItem: ShieldDashboardItem | null = null;
|
||||
|
||||
// Component palette
|
||||
showComponentPalette = false;
|
||||
WidgetsMock: WidgetModel[] = [
|
||||
@@ -51,10 +77,22 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
}
|
||||
];
|
||||
|
||||
// Services data
|
||||
storedata: any[] = [];
|
||||
columnData: any[] = [];
|
||||
sureconnectData: any[] = [];
|
||||
drilldownColumnData: any[] = [];
|
||||
layerColumnData: { [key: number]: any[] } = {};
|
||||
|
||||
// Keep track of deleted items
|
||||
deletedItems: Array<ShieldDashboardItem> = [];
|
||||
|
||||
constructor() { }
|
||||
constructor(
|
||||
private _fb: FormBuilder,
|
||||
private datastoreService: DatastoreService,
|
||||
private alertService: AlertsService,
|
||||
private sureconnectService: SureconnectService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.options = {
|
||||
@@ -81,6 +119,33 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
|
||||
// Initialize the dashboard with empty canvas
|
||||
this.dashboard = [];
|
||||
|
||||
// Initialize form
|
||||
this.configForm = this._fb.group({
|
||||
charttitle: [''],
|
||||
connection: [''],
|
||||
table: [''],
|
||||
xAxis: [''],
|
||||
yAxis: [''],
|
||||
chartlegend: [true],
|
||||
showlabel: [true]
|
||||
});
|
||||
|
||||
// Load service data
|
||||
this.loadServicesData();
|
||||
}
|
||||
|
||||
// Load initial data from services
|
||||
loadServicesData() {
|
||||
// Load sureconnect data
|
||||
this.sureconnectService.getAll().subscribe((data: any[]) => {
|
||||
this.sureconnectData = data;
|
||||
});
|
||||
|
||||
// Load datastore data
|
||||
this.datastoreService.getAll().subscribe((data) => {
|
||||
this.storedata = data as any[];
|
||||
});
|
||||
}
|
||||
|
||||
// Toggle component palette visibility
|
||||
@@ -128,7 +193,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
x: 0,
|
||||
chartType: 'bar-chart',
|
||||
name: 'Bar Chart',
|
||||
id: newId
|
||||
id: newId,
|
||||
chartlegend: true,
|
||||
showlabel: true,
|
||||
baseFilters: [],
|
||||
drilldownEnabled: false,
|
||||
drilldownLayers: []
|
||||
};
|
||||
break;
|
||||
case "doughnut_chart":
|
||||
@@ -142,7 +212,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
x: 0,
|
||||
chartType: 'donut-chart',
|
||||
name: 'End Customer Donut',
|
||||
id: newId
|
||||
id: newId,
|
||||
chartlegend: true,
|
||||
showlabel: true,
|
||||
baseFilters: [],
|
||||
drilldownEnabled: false,
|
||||
drilldownLayers: []
|
||||
};
|
||||
} else {
|
||||
newItem = {
|
||||
@@ -152,7 +227,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
x: 0,
|
||||
chartType: 'donut-chart',
|
||||
name: 'Segment Penetration Donut',
|
||||
id: newId
|
||||
id: newId,
|
||||
chartlegend: true,
|
||||
showlabel: true,
|
||||
baseFilters: [],
|
||||
drilldownEnabled: false,
|
||||
drilldownLayers: []
|
||||
};
|
||||
}
|
||||
break;
|
||||
@@ -164,7 +244,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
x: 0,
|
||||
chartType: 'map-chart',
|
||||
name: 'Map Chart',
|
||||
id: newId
|
||||
id: newId,
|
||||
chartlegend: true,
|
||||
showlabel: true,
|
||||
baseFilters: [],
|
||||
drilldownEnabled: false,
|
||||
drilldownLayers: []
|
||||
};
|
||||
break;
|
||||
case "grid_view":
|
||||
@@ -175,7 +260,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
x: 0,
|
||||
chartType: 'data-table',
|
||||
name: 'Data Table',
|
||||
id: newId
|
||||
id: newId,
|
||||
chartlegend: true,
|
||||
showlabel: true,
|
||||
baseFilters: [],
|
||||
drilldownEnabled: false,
|
||||
drilldownLayers: []
|
||||
};
|
||||
break;
|
||||
case "to_do_chart":
|
||||
@@ -186,7 +276,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
x: 0,
|
||||
chartType: 'deal-details',
|
||||
name: 'Deal Details',
|
||||
id: newId
|
||||
id: newId,
|
||||
chartlegend: true,
|
||||
showlabel: true,
|
||||
baseFilters: [],
|
||||
drilldownEnabled: false,
|
||||
drilldownLayers: []
|
||||
};
|
||||
break;
|
||||
case "line_chart":
|
||||
@@ -197,7 +292,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
x: 0,
|
||||
chartType: 'quarterwise-flow',
|
||||
name: 'Quarterwise Flow',
|
||||
id: newId
|
||||
id: newId,
|
||||
chartlegend: true,
|
||||
showlabel: true,
|
||||
baseFilters: [],
|
||||
drilldownEnabled: false,
|
||||
drilldownLayers: []
|
||||
};
|
||||
break;
|
||||
default:
|
||||
@@ -208,7 +308,12 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
x: 0,
|
||||
chartType: componentType,
|
||||
name: componentType,
|
||||
id: newId
|
||||
id: newId,
|
||||
chartlegend: true,
|
||||
showlabel: true,
|
||||
baseFilters: [],
|
||||
drilldownEnabled: false,
|
||||
drilldownLayers: []
|
||||
};
|
||||
}
|
||||
|
||||
@@ -256,7 +361,22 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
// Only pass properties that are relevant to chart components
|
||||
const chartInputs = {
|
||||
chartType: item.chartType,
|
||||
name: item.name
|
||||
name: item.name,
|
||||
charttitle: item.charttitle,
|
||||
connection: item.connection,
|
||||
table: item.table,
|
||||
xAxis: item.xAxis,
|
||||
yAxis: item.yAxis,
|
||||
chartlegend: item.chartlegend,
|
||||
showlabel: item.showlabel,
|
||||
baseFilters: item.baseFilters || [],
|
||||
drilldownEnabled: item.drilldownEnabled,
|
||||
drilldownApiUrl: item.drilldownApiUrl,
|
||||
drilldownXAxis: item.drilldownXAxis,
|
||||
drilldownYAxis: item.drilldownYAxis,
|
||||
drilldownParameter: item.drilldownParameter,
|
||||
drilldownFilters: item.drilldownFilters || [],
|
||||
drilldownLayers: item.drilldownLayers || []
|
||||
};
|
||||
|
||||
// Remove undefined properties to avoid passing unnecessary data
|
||||
@@ -268,4 +388,193 @@ export class ShieldDashboardComponent implements OnInit {
|
||||
|
||||
return chartInputs;
|
||||
}
|
||||
|
||||
// Open configuration modal for a chart
|
||||
editGadget(item: ShieldDashboardItem) {
|
||||
console.log('Opening configuration modal for item:', item);
|
||||
this.selectedItem = item;
|
||||
this.modeledit = true; // Use modeledit instead of configModalOpen
|
||||
|
||||
// Initialize form with item data
|
||||
this.configForm.patchValue({
|
||||
charttitle: item.charttitle || '',
|
||||
connection: item.connection || '',
|
||||
table: item.table || '',
|
||||
xAxis: item.xAxis || '',
|
||||
yAxis: item.yAxis || [],
|
||||
chartlegend: item.chartlegend !== undefined ? item.chartlegend : true,
|
||||
showlabel: item.showlabel !== undefined ? item.showlabel : true
|
||||
});
|
||||
|
||||
console.log('Form values after patch:', this.configForm.value);
|
||||
|
||||
// Load columns if table is set
|
||||
if (item.table) {
|
||||
this.getColumns(item.connection, item.table);
|
||||
}
|
||||
|
||||
// Load drilldown columns if drilldown API URL is set
|
||||
if (item.drilldownApiUrl) {
|
||||
this.refreshDrilldownColumns();
|
||||
}
|
||||
}
|
||||
|
||||
// Save configuration changes
|
||||
saveConfiguration() {
|
||||
if (this.selectedItem) {
|
||||
const formData = this.configForm.value;
|
||||
console.log('Saving configuration:', formData);
|
||||
|
||||
// Update the selected item with form data
|
||||
Object.assign(this.selectedItem, formData);
|
||||
|
||||
// Close the modal
|
||||
this.modeledit = false; // Use modeledit instead of configModalOpen
|
||||
this.selectedItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel configuration changes
|
||||
cancelConfiguration() {
|
||||
console.log('Canceling configuration');
|
||||
this.modeledit = false; // Use modeledit instead of configModalOpen
|
||||
this.selectedItem = null;
|
||||
}
|
||||
|
||||
// Get tables from datastore
|
||||
getTables(id: string) {
|
||||
this.alertService.getTablefromstore(parseInt(id, 10)).subscribe(gateway => {
|
||||
console.log(gateway);
|
||||
// Handle table data
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// Get columns from API
|
||||
getColumns(connectionId: string, table: string) {
|
||||
const connId = connectionId ? parseInt(connectionId, 10) : undefined;
|
||||
this.alertService.getColumnfromurl(table, connId).subscribe(data => {
|
||||
console.log('Column data:', data);
|
||||
this.columnData = data;
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
this.columnData = [];
|
||||
});
|
||||
}
|
||||
|
||||
// Refresh drilldown columns
|
||||
refreshDrilldownColumns() {
|
||||
if (this.selectedItem && this.selectedItem.drilldownApiUrl) {
|
||||
const connId = this.selectedItem.connection ? parseInt(this.selectedItem.connection, 10) : undefined;
|
||||
this.alertService.getColumnfromurl(this.selectedItem.drilldownApiUrl, connId).subscribe(data => {
|
||||
console.log('Drilldown column data:', data);
|
||||
this.drilldownColumnData = data;
|
||||
}, (error) => {
|
||||
console.log('Error fetching drilldown columns:', error);
|
||||
this.drilldownColumnData = [];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Add base filter
|
||||
addBaseFilter() {
|
||||
if (this.selectedItem) {
|
||||
if (!this.selectedItem.baseFilters) {
|
||||
this.selectedItem.baseFilters = [];
|
||||
}
|
||||
this.selectedItem.baseFilters.push({ field: '', value: '' });
|
||||
}
|
||||
}
|
||||
|
||||
// Remove base filter
|
||||
removeBaseFilter(index: number) {
|
||||
if (this.selectedItem && this.selectedItem.baseFilters) {
|
||||
this.selectedItem.baseFilters.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Add drilldown filter
|
||||
addDrilldownFilter() {
|
||||
if (this.selectedItem) {
|
||||
if (!this.selectedItem.drilldownFilters) {
|
||||
this.selectedItem.drilldownFilters = [];
|
||||
}
|
||||
this.selectedItem.drilldownFilters.push({ field: '', value: '' });
|
||||
}
|
||||
}
|
||||
|
||||
// Remove drilldown filter
|
||||
removeDrilldownFilter(index: number) {
|
||||
if (this.selectedItem && this.selectedItem.drilldownFilters) {
|
||||
this.selectedItem.drilldownFilters.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Add drilldown layer
|
||||
addDrilldownLayer() {
|
||||
if (this.selectedItem) {
|
||||
if (!this.selectedItem.drilldownLayers) {
|
||||
this.selectedItem.drilldownLayers = [];
|
||||
}
|
||||
this.selectedItem.drilldownLayers.push({
|
||||
enabled: false,
|
||||
apiUrl: '',
|
||||
xAxis: '',
|
||||
yAxis: '',
|
||||
parameter: '',
|
||||
filters: []
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Remove drilldown layer
|
||||
removeDrilldownLayer(index: number) {
|
||||
if (this.selectedItem && this.selectedItem.drilldownLayers) {
|
||||
this.selectedItem.drilldownLayers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Add layer filter
|
||||
addLayerFilter(layerIndex: number) {
|
||||
if (this.selectedItem && this.selectedItem.drilldownLayers) {
|
||||
const layer = this.selectedItem.drilldownLayers[layerIndex];
|
||||
if (layer) {
|
||||
if (!layer.filters) {
|
||||
layer.filters = [];
|
||||
}
|
||||
layer.filters.push({ field: '', value: '' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh drilldown columns for a specific layer
|
||||
refreshDrilldownLayerColumns(layerIndex: number) {
|
||||
if (this.selectedItem && this.selectedItem.drilldownLayers && this.selectedItem.drilldownLayers[layerIndex]) {
|
||||
const layer = this.selectedItem.drilldownLayers[layerIndex];
|
||||
if (layer && layer.apiUrl) {
|
||||
const connId = this.selectedItem.connection ? parseInt(this.selectedItem.connection, 10) : undefined;
|
||||
this.alertService.getColumnfromurl(layer.apiUrl, connId).subscribe(data => {
|
||||
console.log(`Drilldown layer ${layerIndex} column data:`, data);
|
||||
// Store layer column data in the layerColumnData property
|
||||
this.layerColumnData[layerIndex] = data;
|
||||
}, (error) => {
|
||||
console.log(`Error fetching drilldown layer ${layerIndex} columns:`, error);
|
||||
this.layerColumnData[layerIndex] = [];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove layer filter
|
||||
removeLayerFilter(layerIndex: number, filterIndex: number) {
|
||||
if (this.selectedItem && this.selectedItem.drilldownLayers) {
|
||||
const layer = this.selectedItem.drilldownLayers[layerIndex];
|
||||
if (layer && layer.filters) {
|
||||
layer.filters.splice(filterIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { ClarityModule } from '@clr/angular';
|
||||
import { GridsterModule } from 'angular-gridster2';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
@@ -32,6 +32,7 @@ import { LoadingShimmerComponent } from './components/loading-shimmer/loading-sh
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ClarityModule,
|
||||
GridsterModule,
|
||||
NgChartsModule,
|
||||
|
||||
Reference in New Issue
Block a user