dashboard #1
@@ -60,7 +60,7 @@
|
|||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell *matCellDef="let element">
|
<td mat-cell *matCellDef="let element">
|
||||||
<button mat-icon-button (click)="delete(element)">
|
<button mat-icon-button (click)="delete(element)">
|
||||||
<img src="assets/img/recycle-bin.svg" class="icon-small" title="delete" />
|
<img src="assets/img/recycle-bin-line.svg" class="icon-small" title="delete" />
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|||||||
@@ -58,8 +58,6 @@ export class DashboardPageComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
delete(dashboard: Dashboard){
|
delete(dashboard: Dashboard){
|
||||||
|
|
||||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||||
|
|||||||
@@ -11,6 +11,6 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions align="end">
|
<div mat-dialog-actions align="end">
|
||||||
<button mat-button mat-dialog-close>Cancel</button>
|
<button mat-button mat-dialog-close (click)="close()">Cancel</button>
|
||||||
<button class="save-button" mat-button mat-dialog-close (click)="onSaveClick()">Save</button>
|
<button class="save-button" mat-button mat-dialog-close (click)="onSaveClick()">Save</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, ElementRef, ViewChild } from '@angular/core';
|
import { Component, ElementRef, Inject, ViewChild } from '@angular/core';
|
||||||
import { MatDialogRef } from '@angular/material/dialog';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-add-text-dialog',
|
selector: 'app-add-text-dialog',
|
||||||
@@ -10,7 +10,12 @@ export class AddTextDialogComponent {
|
|||||||
|
|
||||||
@ViewChild('textElement') textElement!: ElementRef;
|
@ViewChild('textElement') textElement!: ElementRef;
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<string>){
|
constructor(public dialogRef: MatDialogRef<string|undefined>, @Inject(MAT_DIALOG_DATA) public data: {text: string}){
|
||||||
|
this.text = data.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(): void {
|
||||||
|
this.dialogRef.close(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,12 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
.editable .editable-hovered {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.editable:hover .editable-hovered {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div *ngIf="dashboard === undefined && !error" class="center">
|
<div *ngIf="dashboard === undefined && !error" class="center">
|
||||||
@@ -39,10 +45,12 @@
|
|||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<button mat-button (click)="addText()">Add Text</button>
|
<button mat-button (click)="addText()">Add Text</button>
|
||||||
<button mat-button (click)="addPlot()">Add Plot</button>
|
<button mat-button (click)="addPlot()">Add Plot</button>
|
||||||
<button class="save-button" mat-button (click)="save()">Save Dashboard</button>
|
<button class="save-button" mat-button (click)="save()">Save</button>
|
||||||
|
</div>
|
||||||
|
<div class="editable">
|
||||||
|
<h1>{{dashboard.name}}<button mat-icon-button (click)="editNameAndDescription()" class="editable-hovered"><img src="/assets/img/edit-outline.svg"/></button></h1>
|
||||||
|
<p>{{dashboard.description}}</p>
|
||||||
</div>
|
</div>
|
||||||
<h1>{{dashboard.name}}</h1>
|
|
||||||
<p>{{dashboard.description}}</p>
|
|
||||||
|
|
||||||
<div cdkDropListGroup>
|
<div cdkDropListGroup>
|
||||||
<!-- All lists in here will be connected. -->
|
<!-- All lists in here will be connected. -->
|
||||||
@@ -53,12 +61,12 @@
|
|||||||
[cdkDropListData]="column"
|
[cdkDropListData]="column"
|
||||||
(cdkDropListDropped)="drop($event)">
|
(cdkDropListDropped)="drop($event)">
|
||||||
<div
|
<div
|
||||||
cdkDrag
|
cdkDrag
|
||||||
*ngFor="let id of column"
|
*ngFor="let id of column"
|
||||||
[attr.widget-id]="id">
|
[attr.widget-id]="id">
|
||||||
<app-text-widget
|
<app-text-widget
|
||||||
*ngIf="isTextWidget(id)"
|
*ngIf="isTextWidget(id)"
|
||||||
[text]="getTextWidget(id)!.text"></app-text-widget>
|
[data]="getTextWidget(id)!"></app-text-widget>
|
||||||
<app-plot-widget
|
<app-plot-widget
|
||||||
*ngIf="isPlotWidget(id)"
|
*ngIf="isPlotWidget(id)"
|
||||||
[data]="getPlotWidget(id)!"></app-plot-widget>
|
[data]="getPlotWidget(id)!"></app-plot-widget>
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import { Component, ElementRef, OnInit } from '@angular/core';
|
|||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { BaseWidget, Dashboard, DashboardService, PlotSize, PlotWidget, PlotWidgetRenderData, TextWidget } from 'src/app/dashboard.service';
|
import { BaseWidget, Dashboard, DashboardCreationData, DashboardService, PlotSize, PlotWidget, PlotWidgetRenderData, TextWidget } from 'src/app/dashboard.service';
|
||||||
import { PlotConfig, PlotRequest, PlotResponse, PlotService, RenderOptions } from 'src/app/plot.service';
|
import { PlotConfig, PlotRequest, PlotResponse, PlotService, RenderOptions } from 'src/app/plot.service';
|
||||||
|
import { NewDashboardComponent } from '../new-dashboard/new-dashboard.component';
|
||||||
import { AddPlotDialogComponent } from './add-plot-dialog/add-plot-dialog.component';
|
import { AddPlotDialogComponent } from './add-plot-dialog/add-plot-dialog.component';
|
||||||
import { AddTextDialogComponent } from './add-text-dialog/add-text-dialog.component';
|
import { AddTextDialogComponent } from './add-text-dialog/add-text-dialog.component';
|
||||||
|
|
||||||
@@ -141,6 +142,7 @@ export class DashboardComponent implements OnInit {
|
|||||||
|
|
||||||
addText() {
|
addText() {
|
||||||
this.dialog.open(AddTextDialogComponent,{
|
this.dialog.open(AddTextDialogComponent,{
|
||||||
|
data: {text:""},
|
||||||
width: '600px'
|
width: '600px'
|
||||||
}).afterClosed().subscribe((text: string) => {
|
}).afterClosed().subscribe((text: string) => {
|
||||||
const widget = new TextWidget(crypto.randomUUID(),'MEDIUM', text);
|
const widget = new TextWidget(crypto.randomUUID(),'MEDIUM', text);
|
||||||
@@ -184,7 +186,18 @@ export class DashboardComponent implements OnInit {
|
|||||||
|
|
||||||
this.service.saveDashboard(this.dashboard!).subscribe({
|
this.service.saveDashboard(this.dashboard!).subscribe({
|
||||||
'complete': () => {
|
'complete': () => {
|
||||||
this.snackBar.open("saved dashboard","", {
|
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,
|
duration: 5000,
|
||||||
verticalPosition: 'top'
|
verticalPosition: 'top'
|
||||||
});
|
});
|
||||||
@@ -192,6 +205,22 @@ export class DashboardComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
isTextWidget(id: string): boolean {
|
||||||
return this.getTextWidget(id) !== undefined;
|
return this.getTextWidget(id) !== undefined;
|
||||||
}
|
}
|
||||||
@@ -220,8 +249,4 @@ export class DashboardComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s(a: any){
|
|
||||||
return JSON.stringify(a);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,30 @@
|
|||||||
<style>
|
<style>
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 1em;
|
}
|
||||||
background-color: aliceblue;
|
.text-widget {
|
||||||
|
position: relative;
|
||||||
|
padding: 1em 0;
|
||||||
|
}
|
||||||
|
.text-widget:hover {
|
||||||
|
outline: solid 1px black;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editable-hovered {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-widget .editable-hovered {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.text-widget:hover .editable-hovered {
|
||||||
|
visibility: visible;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<p *ngFor="let line of lines()">{{line}}</p>
|
<div class="text-widget">
|
||||||
|
<button mat-icon-button (click)="edit()" class="editable-hovered"><img src="/assets/img/edit-outline.svg"/></button>
|
||||||
|
<p *ngFor="let line of lines()">{{line}}</p>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { TextWidget } from 'src/app/dashboard.service';
|
||||||
|
import { AddTextDialogComponent } from '../add-text-dialog/add-text-dialog.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-text-widget',
|
selector: 'app-text-widget',
|
||||||
@@ -6,9 +9,22 @@ import { Component, Input } from '@angular/core';
|
|||||||
})
|
})
|
||||||
export class TextWidgetComponent {
|
export class TextWidgetComponent {
|
||||||
@Input()
|
@Input()
|
||||||
text = "";
|
data! : TextWidget;
|
||||||
|
|
||||||
|
constructor(private dialog: MatDialog){}
|
||||||
|
|
||||||
lines(): string[]{
|
lines(): string[]{
|
||||||
return typeof this.text == 'string' ? this.text.split(/\r?\n/) : [];
|
return typeof this.data.text == 'string' ? this.data.text.split(/\r?\n/) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
edit() {
|
||||||
|
this.dialog.open(AddTextDialogComponent,{
|
||||||
|
data: {text : this.data.text},
|
||||||
|
width: '600px'
|
||||||
|
}).afterClosed().subscribe((text?: string) => {
|
||||||
|
if (text !== undefined) {
|
||||||
|
this.data.text = text;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
pdb-js/src/assets/img/edit-note-outline.svg
Normal file
1
pdb-js/src/assets/img/edit-note-outline.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24" viewBox="0 0 24 24" width="24"><rect fill="none" height="24" width="24"/><path d="M3,10h11v2H3V10z M3,8h11V6H3V8z M3,16h7v-2H3V16z M18.01,12.87l0.71-0.71c0.39-0.39,1.02-0.39,1.41,0l0.71,0.71 c0.39,0.39,0.39,1.02,0,1.41l-0.71,0.71L18.01,12.87z M17.3,13.58l-5.3,5.3V21h2.12l5.3-5.3L17.3,13.58z"/></svg>
|
||||||
|
After Width: | Height: | Size: 386 B |
1
pdb-js/src/assets/img/edit-outline.svg
Normal file
1
pdb-js/src/assets/img/edit-outline.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z"/></svg>
|
||||||
|
After Width: | Height: | Size: 348 B |
Reference in New Issue
Block a user