Commit bcdcfd00 by Ooh-Ao

วิดเจ็ท

parent 82b33d42
...@@ -161,12 +161,13 @@ ...@@ -161,12 +161,13 @@
[panels]="panels" [panels]="panels"
#editLayout #editLayout
[allowResizing]="true" [allowResizing]="true"
[allowDragging]="true"
> >
<e-panels> <e-panels>
<e-panel <e-panel
*ngFor="let panel of panels" *ngFor="let panel of panels"
[id]="panel.id" [id]="panel.id + '-' + panel.row + '-' + panel.col"
[sizeX]="panel.sizeX" [sizeX]="panel.sizeX"
[sizeY]="panel.sizeY" [sizeY]="panel.sizeY"
[row]="panel.row" [row]="panel.row"
...@@ -183,7 +184,7 @@ ...@@ -183,7 +184,7 @@
<i class="bi bi-gear"></i> <i class="bi bi-gear"></i>
</button> </button>
<button <button
(click)="removeWidgetFromDashboard(panel.id!)" (click)="removeWidgetFromDashboard(panel.id + '-' + panel.row + '-' + panel.col)"
class="text-red-500 hover:text-red-700" class="text-red-500 hover:text-red-700"
> >
<i class="bi bi-trash"></i> <i class="bi bi-trash"></i>
......
...@@ -74,7 +74,8 @@ export class DashboardManagementComponent implements OnInit { ...@@ -74,7 +74,8 @@ export class DashboardManagementComponent implements OnInit {
@ViewChild('editLayout') public layout!: DashboardLayoutComponent; @ViewChild('editLayout') public layout!: DashboardLayoutComponent;
public panels: DashboardPanel[] = []; public panels: DashboardPanel[] = [];
public cellSpacing: number[] = [10, 10]; public cellSpacing: number[] = [10, 10];
public columns: number = 5; public columns: number = 6;
public rows: number = 6;
public availableWidgets: MenuItemsWidget[] = []; public availableWidgets: MenuItemsWidget[] = [];
public filteredAvailableWidgets: MenuItemsWidget[] = []; public filteredAvailableWidgets: MenuItemsWidget[] = [];
public widgetSearchTerm: string = ''; public widgetSearchTerm: string = '';
...@@ -143,6 +144,16 @@ export class DashboardManagementComponent implements OnInit { ...@@ -143,6 +144,16 @@ export class DashboardManagementComponent implements OnInit {
).subscribe(dashboard => { ).subscribe(dashboard => {
if (dashboard) { if (dashboard) {
this.dashboardData = dashboard; this.dashboardData = dashboard;
// Ensure all widgets have a unique instanceId for this session
if (dashboard.widgets) {
dashboard.widgets.forEach((widget: any) => {
if (!widget.instanceId) {
widget.instanceId = `inst_${Date.now()}_${Math.random()}`;
}
});
}
this.panels = this.mapWidgetsToPanels(dashboard.widgets || []); this.panels = this.mapWidgetsToPanels(dashboard.widgets || []);
if (dashboard.datasetId) { if (dashboard.datasetId) {
this.dashboardStateService.selectDataset(dashboard.datasetId); this.dashboardStateService.selectDataset(dashboard.datasetId);
...@@ -231,28 +242,30 @@ export class DashboardManagementComponent implements OnInit { ...@@ -231,28 +242,30 @@ export class DashboardManagementComponent implements OnInit {
} }
} }
onPanelChange(args: any): void { // onPanelChange(args: any): void {
if (this.dashboardData && args.changedPanels) { // if (this.dashboardData && args.changedPanels) {
args.changedPanels.forEach((changedPanel: PanelModel) => { // args.changedPanels.forEach((changedPanel: PanelModel) => {
const widgetIndex = this.dashboardData!.widgets.findIndex(w => w.widgetId === changedPanel.id); // const widgetIndex = this.dashboardData!.widgets.findIndex(w => w.widgetId+"-" + w.y + "-" + w.x === changedPanel.id);
if (widgetIndex > -1) { // if (widgetIndex > -1) {
const updatedWidget = { ...this.dashboardData!.widgets[widgetIndex] }; // const updatedWidget = { ...this.dashboardData!.widgets[widgetIndex] };
updatedWidget.cols = changedPanel.sizeX!; // updatedWidget.cols = changedPanel.sizeX!;
updatedWidget.rows = changedPanel.sizeY!; // updatedWidget.rows = changedPanel.sizeY!;
updatedWidget.x = changedPanel.col!; // updatedWidget.x = changedPanel.col!;
updatedWidget.y = changedPanel.row!; // updatedWidget.y = changedPanel.row!;
this.dashboardData!.widgets[widgetIndex] = updatedWidget; // this.dashboardData!.widgets[widgetIndex] = updatedWidget;
} // }
}); // });
} // }
} // }
saveLayout(): void { saveLayout(): void {
if (!this.dashboardData || !this.layout) return; if (!this.dashboardData || !this.layout) return;
const currentPanels = this.layout.serialize(); const currentPanels = this.layout.serialize();
currentPanels.forEach((panel: PanelModel) => { currentPanels.forEach((panel: PanelModel) => {
const widgetIndex = this.dashboardData!.widgets.findIndex(w => w.widgetId === panel.id); console.log(`Panel ID: ${panel.id}, Col: ${panel.col}, Row: ${panel.row}, SizeX: ${panel.sizeX}, SizeY: ${panel.sizeY}`);
const widgetIndex = this.dashboardData!.widgets.findIndex((w: any) => panel.id && panel.id.startsWith(w.instanceId));
if (widgetIndex > -1) { if (widgetIndex > -1) {
this.dashboardData!.widgets[widgetIndex].x = panel.col!; this.dashboardData!.widgets[widgetIndex].x = panel.col!;
this.dashboardData!.widgets[widgetIndex].y = panel.row!; this.dashboardData!.widgets[widgetIndex].y = panel.row!;
...@@ -260,12 +273,16 @@ export class DashboardManagementComponent implements OnInit { ...@@ -260,12 +273,16 @@ export class DashboardManagementComponent implements OnInit {
this.dashboardData!.widgets[widgetIndex].rows = panel.sizeY!; this.dashboardData!.widgets[widgetIndex].rows = panel.sizeY!;
} }
}); });
console.log('Current panels from layout:', currentPanels);
console.log('Updated widget positions:', this.dashboardData.widgets);
const dashboardToSave = JSON.parse(JSON.stringify(this.dashboardData)); const dashboardToSave = JSON.parse(JSON.stringify(this.dashboardData));
if (dashboardToSave.widgets) { if (dashboardToSave.widgets) {
const allWidgetStates = this.widgetStateService.getAllWidgetStates(); // Get all current widget states const allWidgetStates = this.widgetStateService.getAllWidgetStates(); // Get all current widget states
dashboardToSave.widgets.forEach((widget: WidgetModel) => { dashboardToSave.widgets.forEach((widget: any) => {
// Remove the internal-only instanceId before saving
delete widget.instanceId;
if (widget.config && typeof widget.config === 'object') { if (widget.config && typeof widget.config === 'object') {
widget.config = JSON.stringify(widget.config); widget.config = JSON.stringify(widget.config);
} }
...@@ -301,8 +318,16 @@ export class DashboardManagementComponent implements OnInit { ...@@ -301,8 +318,16 @@ export class DashboardManagementComponent implements OnInit {
} }
// Create a new widget instance from the menu item's widget template // Create a new widget instance from the menu item's widget template
const newWidgetInstance = new WidgetModel(menuItem.widget); const newWidgetInstance = new WidgetModel(menuItem.widget) as any;
if(menuItem.config) { newWidgetInstance.instanceId = `inst_${Date.now()}_${Math.random()}`;
// --- FIX: Calculate next available position ---
const nextY = Math.max(0, ...this.dashboardData.widgets.map(w => (w.y || 0) + (w.rows || 1)));
newWidgetInstance.y = nextY;
newWidgetInstance.x = 0;
// --- END FIX ---
if (menuItem.config) {
newWidgetInstance.config = menuItem.config; newWidgetInstance.config = menuItem.config;
} }
// Ensure the config is an object // Ensure the config is an object
...@@ -322,8 +347,8 @@ export class DashboardManagementComponent implements OnInit { ...@@ -322,8 +347,8 @@ export class DashboardManagementComponent implements OnInit {
removeWidgetFromDashboard(panelId: string): void { removeWidgetFromDashboard(panelId: string): void {
if (!this.dashboardData) return; if (!this.dashboardData) return;
if (confirm('Are you sure you want to remove this widget?')) { if (confirm('Are you sure you want to remove this widget?' + panelId)) {
this.dashboardData.widgets = this.dashboardData.widgets.filter(w => w.widgetId !== panelId); this.dashboardData.widgets = this.dashboardData.widgets.filter((w: any) => w.instanceId !== panelId);
this.panels = this.mapWidgetsToPanels(this.dashboardData.widgets); this.panels = this.mapWidgetsToPanels(this.dashboardData.widgets);
} }
} }
...@@ -350,7 +375,7 @@ export class DashboardManagementComponent implements OnInit { ...@@ -350,7 +375,7 @@ export class DashboardManagementComponent implements OnInit {
dialogRef.afterClosed().subscribe(result => { dialogRef.afterClosed().subscribe(result => {
if (result && this.dashboardData) { if (result && this.dashboardData) {
const widgetIndex = this.dashboardData.widgets.findIndex(w => w.widgetId === widget.widgetId); const widgetIndex = this.dashboardData.widgets.indexOf(panel.originalWidget);
if (widgetIndex > -1) { if (widgetIndex > -1) {
this.dashboardData.widgets[widgetIndex].config = result; this.dashboardData.widgets[widgetIndex].config = result;
this.panels = this.mapWidgetsToPanels(this.dashboardData.widgets); this.panels = this.mapWidgetsToPanels(this.dashboardData.widgets);
...@@ -376,9 +401,9 @@ export class DashboardManagementComponent implements OnInit { ...@@ -376,9 +401,9 @@ export class DashboardManagementComponent implements OnInit {
// Inject widgetId into the config for the component // Inject widgetId into the config for the component
configObject.widgetId = widget.widgetId; configObject.widgetId = widget.widgetId;
console.log(`Mapping widget ${widget.widgetId} to panel with config:`, configObject);
return { return {
id: widget.widgetId, id: `${(widget as any).instanceId}-${widget.y}-${widget.x}`,
header: widget.thName, header: widget.thName,
sizeX: widget.cols, sizeX: widget.cols,
sizeY: widget.rows, sizeY: widget.rows,
......
::ng-deep {
#dashboard_viewer.e-dashboardlayout .e-panel {
background-color: transparent !important;
border: none !important;
box-shadow: none !important;
}
#dashboard_viewer.e-dashboardlayout .e-panel .e-panel-header {
display: none !important;
}
}
.dashboard-viewer-container {
width: 100%;
height: 100%;
}
...@@ -114,8 +114,13 @@ export class DashboardViewerComponent implements OnInit { ...@@ -114,8 +114,13 @@ export class DashboardViewerComponent implements OnInit {
).subscribe({ ).subscribe({
next: dashboard => { next: dashboard => {
if (dashboard) { if (dashboard) {
// Ensure all widgets have a unique instanceId for this session
if (dashboard.widgets) { if (dashboard.widgets) {
dashboard.widgets.forEach(widget => { dashboard.widgets.forEach((widget: any) => {
if (!widget.instanceId) {
widget.instanceId = `inst_${Date.now()}_${Math.random()}`;
}
const keysToProcess: Array<keyof WidgetModel> = ['config', 'data']; const keysToProcess: Array<keyof WidgetModel> = ['config', 'data'];
keysToProcess.forEach(key => { keysToProcess.forEach(key => {
if ((widget as any)[key] && typeof (widget as any)[key] === 'string') { if ((widget as any)[key] && typeof (widget as any)[key] === 'string') {
...@@ -146,7 +151,7 @@ export class DashboardViewerComponent implements OnInit { ...@@ -146,7 +151,7 @@ export class DashboardViewerComponent implements OnInit {
mapWidgetsToPanels(widgets: WidgetModel[]): DashboardPanel[] { mapWidgetsToPanels(widgets: WidgetModel[]): DashboardPanel[] {
return widgets.map(widget => { return widgets.map(widget => {
return { return {
id: widget.widgetId, id: `${(widget as any).instanceId}-${widget.y}-${widget.x}`,
header: widget.thName, header: widget.thName,
sizeX: widget.cols, sizeX: widget.cols,
sizeY: widget.rows, sizeY: widget.rows,
......
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