You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2021/10/13 07:56:47 UTC
[incubator-streampipes] 02/04: [STREAMPIPES-444] Links can be
placed on asset dashboards
This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
commit dc2ede561d9ec74bfbbe23304654b0c58121022f
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Wed Oct 13 09:38:50 2021 +0200
[STREAMPIPES-444] Links can be placed on asset dashboards
---
.../client/assetdashboard/CanvasAttributes.java | 28 +++++++++++
.../app-asset-monitoring.module.ts | 4 +-
.../create-asset/create-asset.component.html | 36 +++++++++-----
.../create-asset/create-asset.component.ts | 30 ++++++++++--
.../components/view-asset/view-asset.component.ts | 23 +++++++++
.../dialog/add-link/add-link-dialog.component.html | 49 +++++++++++++++++++
.../add-link/add-link-dialog.component.scss} | 16 ++-----
.../dialog/add-link/add-link-dialog.component.ts | 56 ++++++++++++++++++++++
.../model/selected-visualization-data.model.ts | 8 +++-
.../app-asset-monitoring/services/shape.service.ts | 39 +++++++++++++--
10 files changed, 256 insertions(+), 33 deletions(-)
diff --git a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/assetdashboard/CanvasAttributes.java b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/assetdashboard/CanvasAttributes.java
index 596d5e2..62149be 100644
--- a/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/assetdashboard/CanvasAttributes.java
+++ b/streampipes-model-client/src/main/java/org/apache/streampipes/model/client/assetdashboard/CanvasAttributes.java
@@ -38,6 +38,10 @@ public class CanvasAttributes {
private String topic;
private String name;
+ private String hyperlink;
+ private boolean newWindow;
+ private String fontStyle;
+
public CanvasAttributes() {
}
@@ -168,4 +172,28 @@ public class CanvasAttributes {
public void setFontSize(String fontSize) {
this.fontSize = fontSize;
}
+
+ public String getHyperlink() {
+ return hyperlink;
+ }
+
+ public void setHyperlink(String hyperlink) {
+ this.hyperlink = hyperlink;
+ }
+
+ public boolean isNewWindow() {
+ return newWindow;
+ }
+
+ public void setNewWindow(boolean newWindow) {
+ this.newWindow = newWindow;
+ }
+
+ public String getFontStyle() {
+ return fontStyle;
+ }
+
+ public void setFontStyle(String fontStyle) {
+ this.fontStyle = fontStyle;
+ }
}
diff --git a/ui/src/app/app-asset-monitoring/app-asset-monitoring.module.ts b/ui/src/app/app-asset-monitoring/app-asset-monitoring.module.ts
index a1260a8..8c4f020 100644
--- a/ui/src/app/app-asset-monitoring/app-asset-monitoring.module.ts
+++ b/ui/src/app/app-asset-monitoring/app-asset-monitoring.module.ts
@@ -40,6 +40,7 @@ import {SaveDashboardDialogComponent} from "./dialog/save-dashboard/save-dashboa
import {AssetDashboardOverviewComponent} from "./components/dashboard-overview/dashboard-overview.component";
import {InjectableRxStompConfig, RxStompService, rxStompServiceFactory} from "@stomp/ng2-stompjs";
import {streamPipesStompConfig} from "../dashboard/services/websocket.config";
+import { AddLinkDialogComponent } from './dialog/add-link/add-link-dialog.component';
@NgModule({
imports: [
@@ -56,6 +57,7 @@ import {streamPipesStompConfig} from "../dashboard/services/websocket.config";
AppAssetMonitoringComponent,
CreateAssetComponent,
ViewAssetComponent,
+ AddLinkDialogComponent,
AddPipelineDialogComponent,
SaveDashboardDialogComponent,
AssetDashboardOverviewComponent
@@ -85,4 +87,4 @@ import {streamPipesStompConfig} from "../dashboard/services/websocket.config";
]
})
export class AppAssetMonitoringModule {
-}
\ No newline at end of file
+}
diff --git a/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.html b/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.html
index 8e81443..1e46811 100644
--- a/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.html
+++ b/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.html
@@ -16,19 +16,32 @@
~
-->
-<div fxLayout="column" fxFlex="100" >
+<div fxLayout="column" fxFlex="100">
<input type="file" (change)="handleFileInput($event)" accept="image/*" #file style="display:none;">
<div class="sp-tab-bg sp-blue-bg page-container-nav">
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start center">
- <button color="accent" mat-button mat-icon-button (click)="prepareDashboard()" type="submit" [disabled]="!backgroundImagePresent || !measurementPresent">
- <i class="material-icons">save</i>
- </button>
- <button color="accent" mat-button mat-icon-button (click)="file.click()" type="submit" [disabled]="backgroundImagePresent">
- <i class="material-icons">file_upload</i>
- </button>
- <button color="accent" mat-button mat-icon-button (click)="openAddPipelineDialog()" >
- <i class="material-icons">add</i>
- </button>
+ <div>
+ <button color="accent" class="mat-basic" mat-button (click)="prepareDashboard()" type="submit"
+ [disabled]="!backgroundImagePresent || !measurementPresent">
+ <mat-icon>save</mat-icon> Save
+ </button>
+ </div>
+ <div>
+ <button color="accent" mat-button (click)="file.click()" type="submit"
+ [disabled]="backgroundImagePresent">
+ <i class="material-icons">file_upload</i> Add image
+ </button>
+ </div>
+ <div>
+ <button color="accent" mat-button (click)="openAddPipelineDialog()">
+ <i class="material-icons">add</i> Add value
+ </button>
+ </div>
+ <div>
+ <button color="accent" mat-button (click)="openAddLinkDialog()">
+ <span fxLayoutAlign="start center"><i class="material-icons">link</i> Add link</span>
+ </button>
+ </div>
<div fxFlex="100" fxLayout="row" fxLayoutAlign="end center">
<button color="accent" mat-button mat-icon-button (click)="clearCanvas()" matTooltip="Clear">
<i class="material-icons">
@@ -39,7 +52,8 @@
</div>
</div>
<div id="outerAssemblyArea" class="asset-configuration-board-panel">
- <div id="asset-configuration-board-canvas" class="asset-configuration-board-canvas" fxLayoutAlign="center center">
+ <div id="asset-configuration-board-canvas" class="asset-configuration-board-canvas"
+ fxLayoutAlign="center center">
</div>
</div>
diff --git a/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.ts b/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.ts
index b4dd597..a3e00f4 100644
--- a/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.ts
+++ b/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.ts
@@ -27,6 +27,7 @@ import { PanelType } from '../../../core-ui/dialog/base-dialog/base-dialog.model
import { DialogService } from '../../../core-ui/dialog/base-dialog/base-dialog.service';
import { DashboardConfiguration } from '../../model/dashboard-configuration.model';
import { RestService } from '../../services/rest.service';
+import { AddLinkDialogComponent } from '../../dialog/add-link/add-link-dialog.component';
interface Window {
Image: any;
@@ -214,7 +215,8 @@ export class CreateAssetComponent implements AfterViewInit {
dialogRef.afterClosed().subscribe(result => {
if (result) {
- this.addNewVisulizationItem(result);
+ const visGroup = this.shapeService.makeNewMeasurementShape(result);
+ this.addNewVisulizationItem(visGroup);
this.measurementPresent = true;
this.mainLayer.draw();
}
@@ -222,6 +224,25 @@ export class CreateAssetComponent implements AfterViewInit {
});
}
+ openAddLinkDialog() {
+ this.keyboardListenerActive = false;
+ const dialogRef = this.dialogService.open(AddLinkDialogComponent, {
+ panelType: PanelType.SLIDE_IN_PANEL,
+ title: 'Add link',
+ width: '50vw',
+ data: {
+ }
+ });
+
+ dialogRef.afterClosed().subscribe(result => {
+ if (result) {
+ console.log(result);
+ this.addNewVisulizationItem(result);
+ }
+ this.keyboardListenerActive = true;
+ });
+ }
+
@HostListener('document:keydown', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if (this.keyboardListenerActive) {
@@ -252,8 +273,7 @@ export class CreateAssetComponent implements AfterViewInit {
}
}
- addNewVisulizationItem(visualizationConfig) {
- const visGroup = this.shapeService.makeNewMeasurementShape(visualizationConfig);
+ addNewVisulizationItem(visGroup) {
const id = this.makeId();
visGroup.id(id);
this.mainLayer.add(visGroup);
@@ -264,8 +284,8 @@ export class CreateAssetComponent implements AfterViewInit {
const tr = this.getNewTransformer(id);
this.mainLayer.add(tr);
tr.attachTo(visGroup);
- //this.mainLayer.draw();
- //this.currentlySelectedShape = visGroup;
+ this.mainLayer.draw();
+ this.currentlySelectedShape = visGroup;
}
getNewTransformer(id: string): Konva.Transformer {
diff --git a/ui/src/app/app-asset-monitoring/components/view-asset/view-asset.component.ts b/ui/src/app/app-asset-monitoring/components/view-asset/view-asset.component.ts
index 674deff..d1c08e6 100644
--- a/ui/src/app/app-asset-monitoring/components/view-asset/view-asset.component.ts
+++ b/ui/src/app/app-asset-monitoring/components/view-asset/view-asset.component.ts
@@ -56,11 +56,34 @@ export class ViewAssetComponent {
this.backgroundImageLayer = new Konva.Layer();
this.showImage();
this.mainCanvasStage.add(this.backgroundImageLayer);
+ const labels = this.mainCanvasStage.find('Label');
+ labels.each(label => {
+ label.on('mouseenter', () => this.onMouseEnter(label));
+ label.on('mouseleave', () => this.onMouseLeave(label));
+ label.on('click', () => this.onLinkClicked(label));
+ });
+
this.backgroundImageLayer.moveToBottom();
this.mainCanvasStage.draw();
this.updateMeasurements();
}
+ onMouseEnter(label) {
+ label.children[0].attrs.fontStyle = 'bold';
+ this.mainCanvasStage.draw();
+ }
+
+ onMouseLeave(label) {
+ label.children[0].attrs.fontStyle = 'normal';
+ this.mainCanvasStage.draw();
+ }
+
+ onLinkClicked(label) {
+ const href = label.children[0].attrs.hyperlink;
+ const newWindow = label.children[0].attrs.newWindow;
+ newWindow ? (window as any).open(href) : (window as any).location.href = href;
+ }
+
updateMeasurements() {
const dynamicShapes = this.mainCanvasStage.find('.dynamic-text');
dynamicShapes.forEach(ds => {
diff --git a/ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.html b/ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.html
new file mode 100644
index 0000000..3a2b81f
--- /dev/null
+++ b/ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.html
@@ -0,0 +1,49 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<div class="sp-dialog-container">
+ <div class="sp-dialog-content p-15">
+ <div fxFlex="100" fxLayout="column">
+ <h4>New link</h4>
+ <div class="dialog-margin-bottom" fxLayout="column">
+ <mat-form-field class="dialog-margin-bottom" color="accent">
+ <mat-label>Label</mat-label>
+ <input matInput placeholder="Label" [(ngModel)]="linkLabel">
+ <mat-hint>The label that should be displayed as link</mat-hint>
+ </mat-form-field>
+ <mat-form-field color="accent">
+ <mat-label>Target</mat-label>
+ <input matInput placeholder="Label" [(ngModel)]="linkHref">
+ <mat-hint>The target URL of the link</mat-hint>
+ </mat-form-field>
+ <mat-checkbox [(ngModel)]="newWindow">Open in new window</mat-checkbox>
+ </div>
+
+ </div>
+ </div>
+ <mat-divider></mat-divider>
+ <div class="sp-dialog-actions">
+ <button mat-button mat-raised-button class="mat-basic mr-10" (click)="cancel()">
+ Cancel
+ </button>
+ <button mat-button mat-raised-button color="accent" (click)="add()">
+ Add
+ </button>
+ </div>
+</div>
+
diff --git a/ui/src/app/app-asset-monitoring/model/selected-visualization-data.model.ts b/ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.scss
similarity index 73%
copy from ui/src/app/app-asset-monitoring/model/selected-visualization-data.model.ts
copy to ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.scss
index 2bcbe28..974d8b1 100644
--- a/ui/src/app/app-asset-monitoring/model/selected-visualization-data.model.ts
+++ b/ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.scss
@@ -16,14 +16,8 @@
*
*/
-export interface SelectedVisualizationData {
- labelBackgroundColor: string;
- labelTextColor: string;
- measurementBackgroundColor: string;
- measurementTextColor: string;
- visualizationId: string;
- measurement: string;
- label: string;
- brokerUrl: string;
- topic: string;
-}
\ No newline at end of file
+@import '../../../../scss/sp/sp-dialog.scss';
+
+.mr-10 {
+ margin-right: 10px;
+}
diff --git a/ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.ts b/ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.ts
new file mode 100644
index 0000000..3e45a79
--- /dev/null
+++ b/ui/src/app/app-asset-monitoring/dialog/add-link/add-link-dialog.component.ts
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, OnInit } from '@angular/core';
+import { DialogRef } from '../../../core-ui/dialog/base-dialog/dialog-ref';
+import { ShapeService } from '../../services/shape.service';
+import { HyperlinkConfig } from '../../model/selected-visualization-data.model';
+
+@Component({
+ selector: 'sp-add-link-dialog-component',
+ templateUrl: 'add-link-dialog.component.html',
+ styleUrls: ['./add-link-dialog.component.scss'],
+})
+export class AddLinkDialogComponent implements OnInit {
+
+ linkLabel: string;
+ linkHref: string;
+ newWindow = false;
+
+ constructor(private dialogRef: DialogRef<AddLinkDialogComponent>,
+ private shapeService: ShapeService) {}
+
+ ngOnInit(): void {
+ }
+
+ cancel() {
+ this.dialogRef.close();
+ }
+
+ add() {
+ const hyperlinkConfig: HyperlinkConfig = {
+ linkLabel: this.linkLabel,
+ linkHref: this.linkHref,
+ newWindow: this.newWindow
+ };
+
+ const group = this.shapeService.makeNewHyperlinkGroup(hyperlinkConfig);
+ this.dialogRef.close(group);
+ }
+
+}
diff --git a/ui/src/app/app-asset-monitoring/model/selected-visualization-data.model.ts b/ui/src/app/app-asset-monitoring/model/selected-visualization-data.model.ts
index 2bcbe28..027482c 100644
--- a/ui/src/app/app-asset-monitoring/model/selected-visualization-data.model.ts
+++ b/ui/src/app/app-asset-monitoring/model/selected-visualization-data.model.ts
@@ -26,4 +26,10 @@ export interface SelectedVisualizationData {
label: string;
brokerUrl: string;
topic: string;
-}
\ No newline at end of file
+}
+
+export interface HyperlinkConfig {
+ linkLabel: string;
+ linkHref: string;
+ newWindow: boolean;
+}
diff --git a/ui/src/app/app-asset-monitoring/services/shape.service.ts b/ui/src/app/app-asset-monitoring/services/shape.service.ts
index 6f0c56d..6e4a698 100644
--- a/ui/src/app/app-asset-monitoring/services/shape.service.ts
+++ b/ui/src/app/app-asset-monitoring/services/shape.service.ts
@@ -20,7 +20,10 @@ import {Injectable} from "@angular/core";
import Konva from "konva";
-import {SelectedVisualizationData} from "../model/selected-visualization-data.model";
+import {
+ HyperlinkConfig,
+ SelectedVisualizationData
+} from "../model/selected-visualization-data.model";
@Injectable()
export class ShapeService {
@@ -29,22 +32,50 @@ export class ShapeService {
}
+ makeNewHyperlinkGroup(hyperlinkConfig: HyperlinkConfig) {
+ const group = this.makeGroup(true);
+ group.add(this.makeHyperlinkLabel(hyperlinkConfig));
+ return group;
+ }
+
+ makeHyperlinkLabel(hyperlinkConfig: HyperlinkConfig): Konva.Label {
+ const label = new Konva.Label({
+ x: 200,
+ y: 40,
+ });
+ label.add(this.makeHyperlinkText(hyperlinkConfig));
+ return label;
+ }
+
+ makeHyperlinkText(hyperlinkConfig: HyperlinkConfig): Konva.Text {
+ const settings: any = {
+ text: hyperlinkConfig.linkLabel,
+ width: 200,
+ height: 20,
+ hyperlink: hyperlinkConfig.linkHref,
+ newWindow: hyperlinkConfig.newWindow,
+ textDecoration: 'underline',
+ fill: '#1b1464',
+ };
+ return new Konva.Text(settings);
+ }
+
makeNewMeasurementShape(visualizationConfig: SelectedVisualizationData): Konva.Group {
- let visualizationGroup = this.makeGroup(true);
+ const visualizationGroup = this.makeGroup(true);
visualizationGroup.add(this.makeLabelGroup(visualizationConfig));
visualizationGroup.add(this.makeMeasurementGroup(visualizationConfig));
return visualizationGroup;
}
makeLabelGroup(config: SelectedVisualizationData): Konva.Group {
- let labelGroup = this.makeGroup(false);
+ const labelGroup = this.makeGroup(false);
labelGroup.add(this.makeRect(config.labelBackgroundColor, 120, 40, 120, 20));
labelGroup.add(this.makeText(config, config.label, config.labelTextColor, 120, 45, 120, 20, false))
return labelGroup;
}
makeMeasurementGroup(config: SelectedVisualizationData): Konva.Group {
- let measurementGroup = this.makeGroup(false);
+ const measurementGroup = this.makeGroup(false);
measurementGroup.add(this.makeRect(config.measurementBackgroundColor, 120, 60, 120, 40));
measurementGroup.add(this.makeText(config, config.measurement, config.measurementTextColor, 120, 65, 120, 40, true))
return measurementGroup;