218 lines
7.0 KiB
TypeScript
218 lines
7.0 KiB
TypeScript
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
|
|
import { HttpErrorResponse } from '@angular/common/http';
|
|
import { Component, ElementRef, OnInit } from '@angular/core';
|
|
import { MatDialog } from '@angular/material/dialog';
|
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
import { ActivatedRoute } from '@angular/router';
|
|
import { Dashboard, DashboardCreationData, DashboardService, PlotWidget, PlotWidgetRenderData, TextWidget } from 'src/app/dashboard.service';
|
|
import { PlotConfig, PlotResponse, PlotService } from 'src/app/plot.service';
|
|
import { NewDashboardComponent } from '../new-dashboard/new-dashboard.component';
|
|
import { AddPlotDialogComponent } from './add-plot-dialog/add-plot-dialog.component';
|
|
import { AddTextDialogComponent } from './add-text-dialog/add-text-dialog.component';
|
|
|
|
@Component({
|
|
selector: 'app-dashboard',
|
|
templateUrl: './dashboard.component.html'
|
|
})
|
|
export class DashboardComponent implements OnInit {
|
|
|
|
dashboard?: Dashboard = undefined;
|
|
|
|
error = "";
|
|
|
|
plotWidgetRenderData: PlotWidgetRenderData[] = [];
|
|
|
|
constructor(
|
|
private route: ActivatedRoute,
|
|
private service: DashboardService,
|
|
private dialog: MatDialog,
|
|
private snackBar: MatSnackBar,
|
|
private plotService: PlotService,
|
|
private element: ElementRef) {}
|
|
|
|
ngOnInit(): void {
|
|
this.service.getDashboard(<string>this.route.snapshot.paramMap.get("id")).subscribe({
|
|
'next':(dashboard: Dashboard) => {
|
|
this.dashboard = dashboard;
|
|
this.repairArrangement();
|
|
|
|
dashboard.plots.forEach(p => {
|
|
this.plotWidgetRenderData.push(new PlotWidgetRenderData(p));
|
|
});
|
|
|
|
this.loadImages(0, this.plotWidgetRenderData);
|
|
},
|
|
'error': (error: HttpErrorResponse) =>{
|
|
if (error.status == 404) {
|
|
this.error = "Not Found";
|
|
}else if (error.status == 504) { // gateway timeout
|
|
this.error = "Server Unreachable";
|
|
}else{
|
|
this.error = "Failed to load dashboard";
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
loadImages(index: number, plotWidgetQueue: PlotWidgetRenderData[]) {
|
|
|
|
if (index < plotWidgetQueue.length){
|
|
const plot = plotWidgetQueue[index];
|
|
const request = PlotWidget.createPlotRequest(plot.widget);
|
|
this.plotService.sendPlotRequest(request).subscribe({
|
|
next: (response: PlotResponse)=> {
|
|
plot.plotResponse= response;
|
|
},
|
|
error: (error:any)=> {},
|
|
complete: () => {
|
|
this.loadImages(index +1 , plotWidgetQueue);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
private repairArrangement(){
|
|
const arrangement = this.dashboard!.arrangement || [];
|
|
if (arrangement.length == 0){
|
|
arrangement[0] = [];
|
|
}
|
|
this.dashboard?.texts.forEach(t => {
|
|
if (!this.arrangmentContainsId(arrangement, t.id)){
|
|
arrangement[0].push(t.id);
|
|
}
|
|
});
|
|
this.dashboard?.plots.forEach(t => {
|
|
if (!this.arrangmentContainsId(arrangement, t.id)){
|
|
arrangement[0].push(t.id);
|
|
}
|
|
});
|
|
this.dashboard!.arrangement = arrangement;
|
|
}
|
|
|
|
private arrangmentContainsId(arrangement: string[][], id: string): boolean{
|
|
|
|
for ( let i = 0; i < arrangement.length; i++){
|
|
if (arrangement[i].includes(id)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
addText() {
|
|
this.dialog.open(AddTextDialogComponent,{
|
|
data: {text:""},
|
|
width: '600px'
|
|
}).afterClosed().subscribe((text: string) => {
|
|
const widget = new TextWidget(crypto.randomUUID(),'MEDIUM', text);
|
|
this.dashboard!.texts.push(widget);
|
|
this.dashboard!.arrangement[0].push(widget.id);
|
|
});
|
|
}
|
|
|
|
addPlot() {
|
|
this.dialog.open(AddPlotDialogComponent,{
|
|
data: {title: "Add Plot"},
|
|
width: 'calc(100% - 1em)',
|
|
height: 'calc(100% - 1em)'
|
|
}).afterClosed().subscribe((config: PlotConfig | "") => {
|
|
if (config != "" && config.query.length > 0) {
|
|
const widget = new PlotWidget(crypto.randomUUID(), 'MEDIUM', config);
|
|
this.dashboard!.plots.push(widget);
|
|
this.dashboard!.arrangement[0].push(widget.id);
|
|
this.plotWidgetRenderData.push(new PlotWidgetRenderData(widget));
|
|
this.loadImages(this.plotWidgetRenderData.length-1, this.plotWidgetRenderData);
|
|
}
|
|
});
|
|
}
|
|
|
|
save() {
|
|
const arrangement = <string[][]>[];
|
|
const dashboardColumns = (<HTMLElement>this.element.nativeElement).querySelectorAll('.dashboard-column');
|
|
for(let i =0; i < dashboardColumns.length; i++){
|
|
const ids = [];
|
|
const column = <HTMLDivElement>dashboardColumns.item(i);
|
|
for(let c = 0; c <column.children.length; c++) {
|
|
const element = <Element>column.children.item(c)
|
|
const id = element!.getAttribute("widget-id");
|
|
if (id !== null) {
|
|
ids.push(id);
|
|
}
|
|
}
|
|
arrangement.push(ids);
|
|
}
|
|
|
|
this.dashboard!.arrangement = arrangement;
|
|
|
|
this.service.saveDashboard(this.dashboard!).subscribe({
|
|
'complete': () => {
|
|
const successMessages = [
|
|
"dashboard saved",
|
|
"saving the dashboard was a complete success",
|
|
"dashboard state securely stored",
|
|
"the save was successful",
|
|
"done",
|
|
"success",
|
|
"saved"
|
|
];
|
|
const randomMessage = successMessages[Math.floor(Math.random()*successMessages.length)];
|
|
|
|
this.snackBar.open(randomMessage,"", {
|
|
duration: 5000,
|
|
verticalPosition: 'top'
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
editNameAndDescription() {
|
|
const dialogRef = this.dialog.open(NewDashboardComponent, {
|
|
data: {name: this.dashboard!.name, description: this.dashboard!.description},
|
|
hasBackdrop: true
|
|
});
|
|
|
|
dialogRef.afterClosed().subscribe((result?: DashboardCreationData) => {
|
|
|
|
if (result) {
|
|
this.dashboard!.name = result.name;
|
|
this.dashboard!.description = result.description;
|
|
}
|
|
});
|
|
}
|
|
|
|
isTextWidget(id: string): boolean {
|
|
return this.getTextWidget(id) !== undefined;
|
|
}
|
|
|
|
isPlotWidget(id: string): boolean {
|
|
return this.dashboard?.plots.find( x => x.id == id) !== undefined;
|
|
}
|
|
|
|
getTextWidget(id: string): TextWidget | undefined {
|
|
return this.dashboard?.texts.find( x => x.id == id);
|
|
}
|
|
|
|
getPlotWidget(id: string): PlotWidgetRenderData | undefined {
|
|
return this.plotWidgetRenderData.find( x => x.widget.id == id);
|
|
}
|
|
|
|
drop(event: CdkDragDrop<string[]>) {
|
|
if (event.previousContainer === event.container) {
|
|
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
|
|
} else {
|
|
transferArrayItem(
|
|
event.previousContainer.data,
|
|
event.container.data,
|
|
event.previousIndex,
|
|
event.currentIndex,
|
|
);
|
|
}
|
|
}
|
|
|
|
delete(dashboardId: string) {
|
|
this.dashboard!.arrangement[0] = this.dashboard!.arrangement[0].filter(a => a != dashboardId);
|
|
this.dashboard!.plots = this.dashboard!.plots.filter(p => p.id != dashboardId);
|
|
this.dashboard!.texts = this.dashboard!.texts.filter(t => t.id != dashboardId);
|
|
}
|
|
}
|