Commit 7d32073b by Ooh-Ao

ดาต้า source

parent fafd66a2
...@@ -683,43 +683,32 @@ export class DashboardManagementComponent implements OnInit { ...@@ -683,43 +683,32 @@ export class DashboardManagementComponent implements OnInit {
} }
saveLayout(): void { saveLayout(): void {
console.log('saveLayout called. Dashboard data to save:', this.dashboardData);
if (!this.dashboardData) return; if (!this.dashboardData) return;
const dataFetchTasks: Observable<any>[] = this.dashboardData.widgets // Create a deep copy to avoid mutating the component's state
.filter(widget => widget.component === 'NewDataTableWidget' && widget.config?.source?.url) const dashboardToSave = JSON.parse(JSON.stringify(this.dashboardData));
.map(widget =>
this.widgetDataService.fetchDataForWidget(widget.config).pipe(
tap(data => {
// Mutate the config object to include the fetched data
widget.config.data = data;
})
)
);
if (dataFetchTasks.length > 0) { // Stringify all widget configs before saving
forkJoin(dataFetchTasks).subscribe(() => { if (dashboardToSave.widgets) {
console.log('All data fetched, now saving dashboard...'); dashboardToSave.widgets.forEach((widget: WidgetModel) => {
this.dashboardDataService.saveDashboard(this.dashboardData!).pipe( if (widget.config && typeof widget.config === 'object') {
catchError(error => { widget.config = JSON.stringify(widget.config);
this.notificationService.error('Error', 'Failed to save dashboard layout.'); }
return throwError(() => error);
})
).subscribe(() => {
this.notificationService.success('Success', 'Dashboard layout saved successfully!');
});
});
} else {
console.log('No data to fetch, saving dashboard directly...');
this.dashboardDataService.saveDashboard(this.dashboardData).pipe(
catchError(error => {
this.notificationService.error('Error', 'Failed to save dashboard layout.');
return throwError(() => error);
})
).subscribe(() => {
this.notificationService.success('Success', 'Dashboard layout saved successfully!');
}); });
} }
console.log('Saving dashboard with stringified configs:', dashboardToSave);
this.dashboardDataService.saveDashboard(dashboardToSave).pipe(
catchError(error => {
this.notificationService.error('Error', 'Failed to save dashboard layout.');
return throwError(() => error);
})
).subscribe(() => {
this.notificationService.success('Success', 'Dashboard layout saved successfully!');
// Optionally, reload the dashboard to ensure UI is consistent with saved state
this.loadSelectedDashboard();
});
} }
// Kept for compatibility with the sidebar, which is not the focus of this refactor // Kept for compatibility with the sidebar, which is not the focus of this refactor
......
...@@ -148,24 +148,35 @@ ...@@ -148,24 +148,35 @@
</div> </div>
<div *ngIf="widgetType === 'ChartWidgetComponent'"> <div *ngIf="widgetType === 'ChartWidgetComponent'">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>Title</mat-label> <mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title"> <input matInput [(ngModel)]="currentConfig.title" name="title">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>X-Axis Field</mat-label> <mat-label>X-Axis Field</mat-label>
<mat-select [(ngModel)]="currentConfig.xField" name="xField"> <mat-select [(ngModel)]="currentConfig.xField" name="xField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option> <mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>Y-Axis Title</mat-label> <mat-label>Y-Axis Title</mat-label>
<input matInput [(ngModel)]="currentConfig.yAxisTitle" name="yAxisTitle"> <input matInput [(ngModel)]="currentConfig.yAxisTitle" name="yAxisTitle">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Y-Axis Fields (JSON Array)</mat-label> <!-- Y-Axis Fields -->
<textarea matInput [(ngModel)]="currentConfig.yFieldsJson" name="yFieldsJson" rows="5"></textarea> <div class="config-section border p-3 rounded-lg mb-4">
</mat-form-field> <h3 class="text-lg font-semibold mb-2">Y-Axis Fields</h3>
<div *ngFor="let yField of currentConfig.yFields; let i = index" class="flex items-center gap-2 mb-2">
<mat-form-field appearance="fill" class="flex-grow">
<mat-label>Field {{i + 1}}</mat-label>
<mat-select [(ngModel)]="currentConfig.yFields[i]" [name]="'yfield_' + i">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
</mat-form-field>
<button mat-icon-button color="warn" (click)="removeChartYField(i)" type="button"><mat-icon>delete</mat-icon></button>
</div>
<button mat-stroked-button color="primary" (click)="addChartYField()" type="button"><mat-icon>add</mat-icon> Add Y-Axis Field</button>
</div>
</div> </div>
<div *ngIf="widgetType === 'QuickLinksWidgetComponent'"> <div *ngIf="widgetType === 'QuickLinksWidgetComponent'">
...@@ -187,39 +198,127 @@ ...@@ -187,39 +198,127 @@
</mat-form-field> </mat-form-field>
</div> </div>
<div *ngIf="widgetType === 'SyncfusionDatagridWidgetComponent'"> <!-- Unified Column Editor for Grid-like Widgets -->
<mat-form-field appearance="fill"> <ng-container *ngIf="widgetType === 'SyncfusionDatagridWidgetComponent' || widgetType === 'NewDataTableWidget' || widgetType === 'MatrixWidgetComponent'">
<mat-form-field appearance="fill" class="w-full">
<mat-label>Title</mat-label> <mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title"> <input matInput [(ngModel)]="currentConfig.title" name="title">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Columns (JSON Array)</mat-label> <h3 class="text-lg font-semibold mt-4 mb-2">Columns</h3>
<textarea matInput [(ngModel)]="currentConfig.columnsJson" name="columnsJson" rows="5"></textarea>
</mat-form-field> <div *ngFor="let column of currentConfig.columns; let i = index" class="column-config-item p-3 mb-3 border rounded-lg">
</div> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 items-center">
<!-- Column Field -->
<mat-form-field appearance="fill">
<mat-label>Field</mat-label>
<mat-select [(ngModel)]="column.field" [name]="'field' + i">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
</mat-form-field>
<!-- Header Text -->
<mat-form-field appearance="fill">
<mat-label>Header Text</mat-label>
<input matInput [(ngModel)]="column.headerText" [name]="'headerText' + i">
</mat-form-field>
<!-- Width -->
<mat-form-field appearance="fill">
<mat-label>Width</mat-label>
<input matInput type="number" [(ngModel)]="column.width" [name]="'width' + i">
</mat-form-field>
<!-- Is Primary Key -->
<mat-checkbox [(ngModel)]="column.isPrimary" [name]="'isPrimary' + i" class="mt-4">
Is Primary Key
</mat-checkbox>
</div>
<!-- Remove Button -->
<div class="flex justify-end mt-2">
<button mat-icon-button color="warn" (click)="removeGridColumn(i)" type="button">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
<button mat-stroked-button color="primary" (click)="addGridColumn()" type="button" class="mt-2">
<mat-icon>add</mat-icon>
Add Column
</button>
</ng-container>
<div *ngIf="widgetType === 'SyncfusionPivotWidgetComponent'"> <div *ngIf="widgetType === 'SyncfusionPivotWidgetComponent'">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>Title</mat-label> <mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title"> <input matInput [(ngModel)]="currentConfig.title" name="title">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <mat-checkbox [(ngModel)]="currentConfig.expandAll" name="expandAll" class="mb-4">Expand All</mat-checkbox>
<mat-label>Rows (JSON Array)</mat-label>
<textarea matInput [(ngModel)]="currentConfig.rowsJson" name="rowsJson" rows="5"></textarea> <!-- Pivot Rows -->
</mat-form-field> <div class="config-section border p-3 rounded-lg mb-4">
<mat-form-field appearance="fill"> <h3 class="text-lg font-semibold mb-2">Rows</h3>
<mat-label>Columns (JSON Array)</mat-label> <div *ngFor="let row of currentConfig.rows; let i = index" class="flex items-center gap-2 mb-2">
<textarea matInput [(ngModel)]="currentConfig.columnsJson" name="columnsJson" rows="5"></textarea> <mat-form-field appearance="fill" class="flex-grow">
</mat-form-field> <mat-label>Row Field</mat-label>
<mat-form-field appearance="fill"> <mat-select [(ngModel)]="row.name" [name]="'row_name_' + i">
<mat-label>Values (JSON Array)</mat-label> <mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
<textarea matInput [(ngModel)]="currentConfig.valuesJson" name="valuesJson" rows="5"></textarea> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <button mat-icon-button color="warn" (click)="removePivotRow(i)" type="button"><mat-icon>delete</mat-icon></button>
<mat-label>Filters (JSON Array)</mat-label> </div>
<textarea matInput [(ngModel)]="currentConfig.filtersJson" name="filtersJson" rows="5"></textarea> <button mat-stroked-button color="primary" (click)="addPivotRow()" type="button"><mat-icon>add</mat-icon> Add Row</button>
</mat-form-field> </div>
<mat-checkbox [(ngModel)]="currentConfig.expandAll" name="expandAll">Expand All</mat-checkbox>
<!-- Pivot Columns -->
<div class="config-section border p-3 rounded-lg mb-4">
<h3 class="text-lg font-semibold mb-2">Columns</h3>
<div *ngFor="let col of currentConfig.columns; let i = index" class="flex items-center gap-2 mb-2">
<mat-form-field appearance="fill" class="flex-grow">
<mat-label>Column Field</mat-label>
<mat-select [(ngModel)]="col.name" [name]="'col_name_' + i">
<mat-option *ngFor="let c of availableColumns" [value]="c">{{ c }}</mat-option>
</mat-select>
</mat-form-field>
<button mat-icon-button color="warn" (click)="removePivotColumn(i)" type="button"><mat-icon>delete</mat-icon></button>
</div>
<button mat-stroked-button color="primary" (click)="addPivotColumn()" type="button"><mat-icon>add</mat-icon> Add Column</button>
</div>
<!-- Pivot Values -->
<div class="config-section border p-3 rounded-lg mb-4">
<h3 class="text-lg font-semibold mb-2">Values</h3>
<div *ngFor="let val of currentConfig.values; let i = index" class="flex items-center gap-2 mb-2">
<mat-form-field appearance="fill" class="flex-grow">
<mat-label>Value Field</mat-label>
<mat-select [(ngModel)]="val.name" [name]="'val_name_' + i">
<mat-option *ngFor="let c of availableColumns" [value]="c">{{ c }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field appearance="fill" class="flex-grow">
<mat-label>Caption</mat-label>
<input matInput [(ngModel)]="val.caption" [name]="'val_caption_' + i">
</mat-form-field>
<button mat-icon-button color="warn" (click)="removePivotValue(i)" type="button"><mat-icon>delete</mat-icon></button>
</div>
<button mat-stroked-button color="primary" (click)="addPivotValue()" type="button"><mat-icon>add</mat-icon> Add Value</button>
</div>
<!-- Pivot Filters -->
<div class="config-section border p-3 rounded-lg">
<h3 class="text-lg font-semibold mb-2">Filters</h3>
<div *ngFor="let fil of currentConfig.filters; let i = index" class="flex items-center gap-2 mb-2">
<mat-form-field appearance="fill" class="flex-grow">
<mat-label>Filter Field</mat-label>
<mat-select [(ngModel)]="fil.name" [name]="'fil_name_' + i">
<mat-option *ngFor="let c of availableColumns" [value]="c">{{ c }}</mat-option>
</mat-select>
</mat-form-field>
<button mat-icon-button color="warn" (click)="removePivotFilter(i)" type="button"><mat-icon>delete</mat-icon></button>
</div>
<button mat-stroked-button color="primary" (click)="addPivotFilter()" type="button"><mat-icon>add</mat-icon> Add Filter</button>
</div>
</div> </div>
<div *ngIf="widgetType === 'SyncfusionChartWidgetComponent'"> <div *ngIf="widgetType === 'SyncfusionChartWidgetComponent'">
...@@ -345,45 +444,78 @@ ...@@ -345,45 +444,78 @@
</div> </div>
<div *ngIf="widgetType === 'ComboChartWidgetComponent'"> <div *ngIf="widgetType === 'ComboChartWidgetComponent'">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>Title</mat-label> <mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title"> <input matInput [(ngModel)]="currentConfig.title" name="title">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>X-Axis Field</mat-label> <mat-label>X-Axis Field</mat-label>
<mat-select [(ngModel)]="currentConfig.xField" name="xField"> <mat-select [(ngModel)]="currentConfig.xField" name="xField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option> <mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>Y-Axis Fields (JSON Array of Strings)</mat-label>
<textarea matInput [(ngModel)]="currentConfig.yFieldsJson" name="yFieldsJson" rows="5"></textarea>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>X-Axis Title</mat-label> <mat-label>X-Axis Title</mat-label>
<input matInput [(ngModel)]="currentConfig.xAxisTitle" name="xAxisTitle"> <input matInput [(ngModel)]="currentConfig.xAxisTitle" name="xAxisTitle">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>Y-Axis Title</mat-label> <mat-label>Y-Axis Title</mat-label>
<input matInput [(ngModel)]="currentConfig.yAxisTitle" name="yAxisTitle"> <input matInput [(ngModel)]="currentConfig.yAxisTitle" name="yAxisTitle">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Series (JSON Array of Objects)</mat-label>
<textarea matInput [(ngModel)]="currentConfig.seriesJson" name="seriesJson" rows="10"></textarea>
</mat-form-field>
</div>
<div *ngIf="widgetType === 'MatrixWidgetComponent'"> <!-- Y-Axis Fields -->
<mat-form-field appearance="fill"> <div class="config-section border p-3 rounded-lg mb-4">
<mat-label>Title</mat-label> <h3 class="text-lg font-semibold mb-2">Y-Axis Fields</h3>
<input matInput [(ngModel)]="currentConfig.title" name="title"> <div *ngFor="let yField of currentConfig.yFields; let i = index" class="flex items-center gap-2 mb-2">
</mat-form-field> <mat-form-field appearance="fill" class="flex-grow">
<mat-form-field appearance="fill"> <mat-label>Field {{i + 1}}</mat-label>
<mat-label>Columns (JSON Array)</mat-label> <mat-select [(ngModel)]="currentConfig.yFields[i]" [name]="'yfield_' + i">
<textarea matInput [(ngModel)]="currentConfig.columnsJson" name="columnsJson" rows="5"></textarea> <mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-form-field> </mat-select>
</mat-form-field>
<button mat-icon-button color="warn" (click)="removeChartYField(i)" type="button"><mat-icon>delete</mat-icon></button>
</div>
<button mat-stroked-button color="primary" (click)="addChartYField()" type="button"><mat-icon>add</mat-icon> Add Y-Axis Field</button>
</div>
<!-- Series Configuration -->
<div class="config-section border p-3 rounded-lg mb-4">
<h3 class="text-lg font-semibold mb-2">Series</h3>
<div *ngFor="let series of currentConfig.series; let i = index" class="series-item p-3 mb-3 border rounded-md">
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-4">
<mat-form-field appearance="fill">
<mat-label>Series Name</mat-label>
<input matInput [(ngModel)]="series.name" [name]="'series_name_' + i">
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Chart Type</mat-label>
<mat-select [(ngModel)]="series.type" [name]="'series_type_' + i">
<mat-option *ngFor="let type of comboChartTypes" [value]="type">{{ type }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>X-Axis Name</mat-label>
<mat-select [(ngModel)]="series.xName" [name]="'series_xName_' + i">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Y-Axis Name</mat-label>
<mat-select [(ngModel)]="series.yName" [name]="'series_yName_' + i">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="flex justify-end">
<button mat-icon-button color="warn" (click)="removeComboSeries(i)" type="button"><mat-icon>delete</mat-icon></button>
</div>
</div>
<button mat-stroked-button color="primary" (click)="addComboSeries()" type="button"><mat-icon>add</mat-icon> Add Series</button>
</div>
</div> </div>
<div *ngIf="widgetType === 'SlicerWidgetComponent'"> <div *ngIf="widgetType === 'SlicerWidgetComponent'">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill">
<mat-label>Title</mat-label> <mat-label>Title</mat-label>
......
...@@ -6,6 +6,8 @@ import { MatFormFieldModule } from '@angular/material/form-field'; ...@@ -6,6 +6,8 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input'; import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
export interface WidgetConfigDialogData { export interface WidgetConfigDialogData {
...@@ -24,7 +26,9 @@ export interface WidgetConfigDialogData { ...@@ -24,7 +26,9 @@ export interface WidgetConfigDialogData {
MatInputModule, MatInputModule,
MatSelectModule, MatSelectModule,
MatButtonModule, MatButtonModule,
MatDialogModule // Add MatDialogModule MatDialogModule,
MatIconModule,
MatCheckboxModule
], ],
templateUrl: './widget-config.component.html', templateUrl: './widget-config.component.html',
styleUrls: ['./widget-config.component.scss'] styleUrls: ['./widget-config.component.scss']
...@@ -33,6 +37,7 @@ export class WidgetConfigComponent implements OnInit { ...@@ -33,6 +37,7 @@ export class WidgetConfigComponent implements OnInit {
currentConfig: any; currentConfig: any;
availableColumns: string[]; availableColumns: string[];
widgetType: string; widgetType: string;
comboChartTypes: string[] = ['Line', 'Column', 'Area', 'Spline'];
constructor( constructor(
public dialogRef: MatDialogRef<WidgetConfigComponent>, public dialogRef: MatDialogRef<WidgetConfigComponent>,
...@@ -40,140 +45,85 @@ export class WidgetConfigComponent implements OnInit { ...@@ -40,140 +45,85 @@ export class WidgetConfigComponent implements OnInit {
) { } ) { }
ngOnInit(): void { ngOnInit(): void {
this.currentConfig = { ...this.data.config }; // Create a copy to avoid direct mutation
this.availableColumns = this.data.availableColumns; this.availableColumns = this.data.availableColumns;
this.widgetType = this.data.widgetType; this.widgetType = this.data.widgetType;
// Special handling for ChartWidgetComponent's yFields // Handle config whether it is a string or an object
if (this.widgetType === 'ChartWidgetComponent' && this.currentConfig.yFields) { try {
this.currentConfig.yFieldsJson = JSON.stringify(this.currentConfig.yFields, null, 2); if (typeof this.data.config === 'string') {
} this.currentConfig = JSON.parse(this.data.config);
// Special handling for SyncfusionDatagridWidgetComponent's columns } else {
if (this.widgetType === 'SyncfusionDatagridWidgetComponent' && this.currentConfig.columns) { // Deep copy config to avoid direct mutation of the original object
this.currentConfig.columnsJson = JSON.stringify(this.currentConfig.columns, null, 2); this.currentConfig = JSON.parse(JSON.stringify(this.data.config || {}));
}
// Special handling for SyncfusionPivotWidgetComponent's properties
if (this.widgetType === 'SyncfusionPivotWidgetComponent') {
if (this.currentConfig.rows) {
this.currentConfig.rowsJson = JSON.stringify(this.currentConfig.rows, null, 2);
}
if (this.currentConfig.columns) {
this.currentConfig.columnsJson = JSON.stringify(this.currentConfig.columns, null, 2);
}
if (this.currentConfig.values) {
this.currentConfig.valuesJson = JSON.stringify(this.currentConfig.values, null, 2);
}
if (this.currentConfig.filters) {
this.currentConfig.filtersJson = JSON.stringify(this.currentConfig.filters, null, 2);
} }
} catch (e) {
console.error('Error parsing widget config:', e);
this.currentConfig = {}; // Default to empty object on error
} }
// Special handling for NewDataTableWidget's columns
if (this.widgetType === 'NewDataTableWidget' && this.currentConfig.columns) {
this.currentConfig.columnsJson = JSON.stringify(this.currentConfig.columns, null, 2);
}
}
onSave(): void { // Initialize arrays if they don't exist
// Special handling for ChartWidgetComponent's yFields const gridLikeWidgets = ['SyncfusionDatagridWidgetComponent', 'NewDataTableWidget', 'MatrixWidgetComponent'];
if (this.widgetType === 'ChartWidgetComponent' && this.currentConfig.yFieldsJson) { if (gridLikeWidgets.includes(this.widgetType) && !this.currentConfig.columns) {
try { this.currentConfig.columns = [];
this.currentConfig.yFields = JSON.parse(this.currentConfig.yFieldsJson);
} catch (e) {
console.error('Invalid JSON for yFields:', e);
alert('Invalid JSON format for Y-Axis Fields. Please correct it.');
return; // Prevent closing dialog with invalid data
}
} }
// Special handling for SyncfusionDatagridWidgetComponent's columns
if (this.widgetType === 'SyncfusionDatagridWidgetComponent' && this.currentConfig.columnsJson) {
try {
this.currentConfig.columns = JSON.parse(this.currentConfig.columnsJson);
} catch (e) {
console.error('Invalid JSON for columns:', e);
alert('Invalid JSON format for Columns. Please correct it.');
return; // Prevent closing dialog with invalid data
}
}
// Special handling for SyncfusionPivotWidgetComponent's properties
if (this.widgetType === 'SyncfusionPivotWidgetComponent') { if (this.widgetType === 'SyncfusionPivotWidgetComponent') {
if (this.currentConfig.rowsJson) { if (!this.currentConfig.rows) this.currentConfig.rows = [];
try { if (!this.currentConfig.columns) this.currentConfig.columns = [];
this.currentConfig.rows = JSON.parse(this.currentConfig.rowsJson); if (!this.currentConfig.values) this.currentConfig.values = [];
} catch (e) { if (!this.currentConfig.filters) this.currentConfig.filters = [];
console.error('Invalid JSON for rows:', e);
alert('Invalid JSON format for Rows. Please correct it.');
return;
}
}
if (this.currentConfig.columnsJson) {
try {
this.currentConfig.columns = JSON.parse(this.currentConfig.columnsJson);
} catch (e) {
console.error('Invalid JSON for columns:', e);
alert('Invalid JSON format for Columns. Please correct it.');
return;
}
}
if (this.currentConfig.valuesJson) {
try {
this.currentConfig.values = JSON.parse(this.currentConfig.valuesJson);
} catch (e) {
console.error('Invalid JSON for values:', e);
alert('Invalid JSON format for Values. Please correct it.');
return;
}
}
if (this.currentConfig.filtersJson) {
try {
this.currentConfig.filters = JSON.parse(this.currentConfig.filtersJson);
} catch (e) {
console.error('Invalid JSON for filters:', e);
alert('Invalid JSON format for Filters. Please correct it.');
return;
}
}
} }
// Special handling for NewDataTableWidget's columns if (this.widgetType === 'ChartWidgetComponent' && !this.currentConfig.yFields) {
if (this.widgetType === 'NewDataTableWidget' && this.currentConfig.columnsJson) { this.currentConfig.yFields = [];
try {
this.currentConfig.columns = JSON.parse(this.currentConfig.columnsJson);
} catch (e) {
console.error('Invalid JSON for columns:', e);
alert('Invalid JSON format for Columns. Please correct it.');
return; // Prevent closing dialog with invalid data
}
} }
// Special handling for ComboChartWidgetComponent's yFields and series
if (this.widgetType === 'ComboChartWidgetComponent') { if (this.widgetType === 'ComboChartWidgetComponent') {
if (this.currentConfig.yFieldsJson) { if (!this.currentConfig.yFields) this.currentConfig.yFields = [];
try { if (!this.currentConfig.series) this.currentConfig.series = [];
this.currentConfig.yFields = JSON.parse(this.currentConfig.yFieldsJson);
} catch (e) {
console.error('Invalid JSON for yFields:', e);
alert('Invalid JSON format for Y-Axis Fields. Please correct it.');
return;
}
}
if (this.currentConfig.seriesJson) {
try {
this.currentConfig.series = JSON.parse(this.currentConfig.seriesJson);
} catch (e) {
console.error('Invalid JSON for series:', e);
alert('Invalid JSON format for Series. Please correct it.');
return;
}
}
}
// Special handling for MatrixWidgetComponent's columns
if (this.widgetType === 'MatrixWidgetComponent' && this.currentConfig.columnsJson) {
try {
this.currentConfig.columns = JSON.parse(this.currentConfig.columnsJson);
} catch (e) {
console.error('Invalid JSON for columns:', e);
alert('Invalid JSON format for Columns. Please correct it.');
return; // Prevent closing dialog with invalid data
}
} }
}
// Methods for Grid-like Widgets
addGridColumn() {
this.currentConfig.columns.push({ field: '', headerText: '', width: 100, isPrimary: false });
}
removeGridColumn(index: number) {
this.currentConfig.columns.splice(index, 1);
}
// Methods for ChartWidgetComponent & ComboChartWidgetComponent yFields
addChartYField() {
this.currentConfig.yFields.push('');
}
removeChartYField(index: number) {
this.currentConfig.yFields.splice(index, 1);
}
// Methods for ComboChartWidgetComponent series
addComboSeries() {
this.currentConfig.series.push({ name: '', type: 'Line', xName: '', yName: '' });
}
removeComboSeries(index: number) {
this.currentConfig.series.splice(index, 1);
}
// Methods for SyncfusionPivotWidgetComponent
addPivotRow() { this.currentConfig.rows.push({ name: '' }); }
removePivotRow(index: number) { this.currentConfig.rows.splice(index, 1); }
addPivotColumn() { this.currentConfig.columns.push({ name: '' }); }
removePivotColumn(index: number) { this.currentConfig.columns.splice(index, 1); }
addPivotValue() { this.currentConfig.values.push({ name: '', caption: '' }); }
removePivotValue(index: number) { this.currentConfig.values.splice(index, 1); }
addPivotFilter() { this.currentConfig.filters.push({ name: '' }); }
removePivotFilter(index: number) { this.currentConfig.filters.splice(index, 1); }
onSave(): void {
// No more JSON parsing needed for the refactored widgets
this.dialogRef.close(this.currentConfig); this.dialogRef.close(this.currentConfig);
} }
......
...@@ -129,18 +129,6 @@ export class DashboardViewerComponent implements OnInit { ...@@ -129,18 +129,6 @@ export class DashboardViewerComponent implements OnInit {
mapWidgetsToPanels(widgets: WidgetModel[]): DashboardPanel[] { mapWidgetsToPanels(widgets: WidgetModel[]): DashboardPanel[] {
return widgets.map(widget => { return widgets.map(widget => {
let widgetConfig: any = {};
if (typeof widget.config === 'string') {
try {
widgetConfig = JSON.parse(widget.config);
} catch (e) {
console.error('Error parsing widget config string:', widget.config, e);
widgetConfig = {}; // Default to empty object on error
}
} else {
widgetConfig = widget.config || {};
}
return { return {
id: widget.widgetId, id: widget.widgetId,
header: widget.thName, header: widget.thName,
...@@ -149,7 +137,7 @@ export class DashboardViewerComponent implements OnInit { ...@@ -149,7 +137,7 @@ export class DashboardViewerComponent implements OnInit {
row: widget.y, row: widget.y,
col: widget.x, col: widget.x,
componentType: this.widgetComponentMap[widget.component], componentType: this.widgetComponentMap[widget.component],
componentInputs: { config: widgetConfig }, componentInputs: { config: widget.config || {} },
}; };
}); });
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment