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 2020/02/09 13:05:10 UTC

[incubator-streampipes] branch new_dashboard updated: STREAMPIPES-58: Add feature to place widgets on dashboard

This is an automated email from the ASF dual-hosted git repository.

riemer pushed a commit to branch new_dashboard
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git


The following commit(s) were added to refs/heads/new_dashboard by this push:
     new 880c98c  STREAMPIPES-58: Add feature to place widgets on dashboard
880c98c is described below

commit 880c98c424bde62dbd975a8cc24ade1d9a124e98
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sun Feb 9 14:04:55 2020 +0100

    STREAMPIPES-58: Add feature to place widgets on dashboard
---
 .../model/dashboard/DashboardEntity.java           | 16 +++++++
 .../streampipes/rest/impl/dashboard/Dashboard.java |  2 +-
 ui/src/app/core-model/dashboard/DashboardWidget.ts |  4 +-
 .../components/panel/dashboard-panel.component.css |  8 ++++
 .../panel/dashboard-panel.component.html           | 11 +++--
 .../components/panel/dashboard-panel.component.ts  | 52 +++++++++++++++++-----
 .../widget/dashboard-widget.component.css          | 18 ++++++++
 .../widget/dashboard-widget.component.html         | 27 ++++++-----
 .../widget/dashboard-widget.component.ts           |  1 +
 .../components/widgets/base/base-config.ts         |  6 +++
 .../components/widgets/base/base-widget.ts         | 11 ++++-
 .../widgets/number/number-config.component.ts      | 15 ++++---
 .../widgets/number/number-viz.component.css        | 12 ++++-
 .../widgets/number/number-viz.component.ts         | 10 +++--
 .../add-visualization-dialog.component.ts          |  3 +-
 ui/src/app/dashboard-v2/models/dashboard.model.ts  |  1 +
 .../app/dashboard-v2/registry/widget-registry.ts   |  9 ++--
 .../sdk/extractor/static-property-extractor.ts     |  2 +-
 .../app/dashboard-v2/services/dashboard.service.ts |  6 ++-
 19 files changed, 162 insertions(+), 52 deletions(-)

diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardEntity.java b/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardEntity.java
index 3033c36..d9e4eac 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardEntity.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardEntity.java
@@ -41,4 +41,20 @@ public abstract class DashboardEntity extends UnnamedStreamPipesEntity {
   public DashboardEntity() {
     super();
   }
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getRev() {
+    return rev;
+  }
+
+  public void setRev(String rev) {
+    this.rev = rev;
+  }
 }
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/dashboard/Dashboard.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/dashboard/Dashboard.java
index cf97738..692effc 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/dashboard/Dashboard.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/dashboard/Dashboard.java
@@ -57,7 +57,7 @@ public class Dashboard extends AbstractRestInterface implements IDashboard {
   @Override
   public Response modifyDashboard(DashboardModel dashboardModel) {
     getDashboardStorage().updateDashboard(dashboardModel);
-    return ok();
+    return ok(getDashboardStorage().getDashboard(dashboardModel.getCouchDbId()));
   }
 
   @DELETE
diff --git a/ui/src/app/core-model/dashboard/DashboardWidget.ts b/ui/src/app/core-model/dashboard/DashboardWidget.ts
index 640b994..70bfa81 100644
--- a/ui/src/app/core-model/dashboard/DashboardWidget.ts
+++ b/ui/src/app/core-model/dashboard/DashboardWidget.ts
@@ -16,10 +16,10 @@ export class DashboardWidget extends UnnamedStreamPipesEntity {
     @RdfProperty('sp:hasDashboardWidgetDataConfig')
     dashboardWidgetDataConfig: VisualizablePipeline;
 
-    @RdfProperty('sp:hasCouchDbId')
+    @RdfProperty('sp:couchDbId')
     _id: string;
 
-    @RdfProperty('sp:hasCouchDbRev')
+    @RdfProperty('sp:couchDbRev')
     _ref:string;
 
     @RdfProperty('sp:hasDashboardWidgetId')
diff --git a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.css b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.css
index b0ebff0..bbc929d 100644
--- a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.css
+++ b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.css
@@ -1,3 +1,11 @@
 .m-20 {
     margin: 20px;
+}
+
+gridster ::ng-deep {
+    background: white;
+}
+
+gridster.edit ::ng-deep {
+    background: #d3d3d3;
 }
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.html b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.html
index 6cc0ef4..5370f19 100644
--- a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.html
+++ b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.html
@@ -1,12 +1,17 @@
 <div fxFlex="100" fxLayout="column" class="m-20">
     <div fxLayout="row wrap" style="margin-bottom:20px;">
-        <button mat-button mat-raised-button color="primary" (click)="addWidget()">Add visualization</button>
+        <button mat-button mat-raised-button color="primary" (click)="toggleEditMode()"
+                style="margin-right:10px;">{{editMode ? 'Save' : 'Edit'}}
+        </button>
+        <button mat-button mat-raised-button color="primary" (click)="addWidget()" [disabled]="!editMode">Add
+            visualization</button>
+
     </div>
 
-    <gridster [options]="options">
+    <gridster [options]="options" [ngClass]="editMode ? 'edit' : ''">
         <ng-container *ngFor="let item of items">
             <gridster-item [item]="item">
-                <dashboard-widget [widget]="item"></dashboard-widget>
+                <dashboard-widget [widget]="item" [editMode]="editMode"></dashboard-widget>
             </gridster-item>
         </ng-container>
     </gridster>
diff --git a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.ts b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.ts
index 2b4f76d..828b9ee 100644
--- a/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.ts
+++ b/ui/src/app/dashboard-v2/components/panel/dashboard-panel.component.ts
@@ -1,10 +1,11 @@
 import {Component, Input, OnInit} from "@angular/core";
 import {Dashboard, DashboardConfig, DashboardItem} from "../../models/dashboard.model";
 import {Subscription} from "rxjs";
-import {MockDashboardService} from "../../services/MockDashboard.service";
 import {GridType} from "angular-gridster2";
 import {MatDialog} from "@angular/material/dialog";
 import {AddVisualizationDialogComponent} from "../../dialogs/add-widget/add-visualization-dialog.component";
+import {DashboardWidget} from "../../../core-model/dashboard/DashboardWidget";
+import {DashboardService} from "../../services/dashboard.service";
 
 @Component({
     selector: 'dashboard-panel',
@@ -20,18 +21,20 @@ export class DashboardPanelComponent implements OnInit {
 
     protected subscription: Subscription;
 
-    constructor(private dashboardService: MockDashboardService,
+    editMode: boolean = false;
+
+    constructor(private dashboardService: DashboardService,
                 public dialog: MatDialog) {}
 
     public ngOnInit() {
         this.options = {
             disablePushOnDrag: true,
-            draggable: { enabled: true },
-            gridType: GridType.Fit,
+            draggable: { enabled: this.editMode },
+            gridType: GridType.ScrollVertical,
             minCols: 8,
             maxCols: 8,
-            minRows: 2,
-            resizable: { enabled: true }
+            minRows: 4,
+            resizable: { enabled: this.editMode }
         };
         this.items = this.dashboard.widgets;
     }
@@ -43,14 +46,39 @@ export class DashboardPanelComponent implements OnInit {
             panelClass: 'custom-dialog-container'
         });
 
-        dialogRef.afterClosed().subscribe(result => {
-            if (result) {
-                console.log(result);
-                // this.addNewVisulizationItem(result);
-                // this.measurementPresent = true;
-                // this.mainLayer.draw();
+        dialogRef.afterClosed().subscribe(widget => {
+            if (widget) {
+                this.addWidgetToDashboard(widget);
+                this.updateDashboard();
             }
         });
     }
 
+    addWidgetToDashboard(widget: DashboardWidget) {
+        let dashboardItem = {} as DashboardItem;
+        dashboardItem.widgetId = widget._id;
+        dashboardItem.id = widget._id;
+        // TODO there should be a widget type DashboardWidget
+        dashboardItem.widgetType = widget.dashboardWidgetSettings.widgetName;
+        dashboardItem.cols = 2;
+        dashboardItem.rows = 2;
+        dashboardItem.x = 0;
+        dashboardItem.y = 0;
+        this.dashboard.widgets.push(dashboardItem);
+    }
+
+    updateDashboard() {
+        this.dashboardService.updateDashboard(this.dashboard).subscribe(result => {
+            this.dashboard._rev = result._rev;
+        })
+    }
+
+    toggleEditMode() {
+        this.editMode = !(this.editMode);
+        this.options.draggable.enabled = this.editMode;
+        this.options.resizable.enabled = this.editMode;
+        this.options.displayGrid = this.editMode ? 'always' : 'none';
+        this.options.api.optionsChanged();
+    }
+
 }
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css
index e94514f..3627cb9 100644
--- a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css
+++ b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.css
@@ -4,4 +4,22 @@
 
 .p-0 {
     padding:0;
+}
+
+.m-0 {
+    margin:0;
+}
+
+.box {
+    display: flex;
+    flex-flow: column;
+    height: 100%;
+}
+
+.box .row.content {
+    flex: 1 1 auto;
+}
+
+.box .row.header {
+    flex: 0 1 auto;
 }
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html
index b4c6d43..2f8713e 100644
--- a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html
+++ b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.html
@@ -1,16 +1,21 @@
 <div style="height:100%;">
-    <div class="assemblyOptions sp-blue-bg">
-        <div flex="100" layout="row" layout-align="start center">
-            <button mat-button mat-raised-button color="primary">
-                <i class="material-icons">save</i>
-            </button>
+    <div class="box">
+        <div class="assemblyOptions sp-blue-bg m-0 row header" *ngIf="editMode">
+            <div fxFlex="100" layout="row" fxLayoutAlign="end center">
+                <button mat-button mat-icon-button color="white">
+                    <i class="material-icons">settings</i>
+                </button>
+                <button mat-button mat-icon-button color="white">
+                    <i class="material-icons">clear</i>
+                </button>
+            </div>
         </div>
-    </div>
-    <div class="sp-blue-border h-100">
-        <!--        <div *ngIf="widget."></div>-->
-        <div *ngIf="widgetLoaded" class="h-100">
-            <div *ngIf="widget.widgetType === 'number'" class="h-100 p-0">
-                <number-viz [widget]="widget" [widgetConfig]="configuredWidget"></number-viz>
+        <div class="sp-blue-border h-100 p-0 row content">
+            <!--        <div *ngIf="widget."></div>-->
+            <div *ngIf="widgetLoaded" class="h-100">
+                <div *ngIf="widget.widgetType === 'number'" class="h-100 p-0">
+                    <number-viz [widget]="widget" [widgetConfig]="configuredWidget"></number-viz>
+                </div>
             </div>
         </div>
     </div>
diff --git a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.ts b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.ts
index 92bd127..08299f1 100644
--- a/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.ts
+++ b/ui/src/app/dashboard-v2/components/widget/dashboard-widget.component.ts
@@ -12,6 +12,7 @@ import {DashboardWidget} from "../../../core-model/dashboard/DashboardWidget";
 export class DashboardWidgetComponent implements OnInit {
 
     @Input() widget: DashboardItem;
+    @Input() editMode: boolean;
 
     widgetLoaded: boolean = false;
     configuredWidget: DashboardWidget;
diff --git a/ui/src/app/dashboard-v2/components/widgets/base/base-config.ts b/ui/src/app/dashboard-v2/components/widgets/base/base-config.ts
new file mode 100644
index 0000000..2ed5443
--- /dev/null
+++ b/ui/src/app/dashboard-v2/components/widgets/base/base-config.ts
@@ -0,0 +1,6 @@
+import {DashboardWidgetSettings} from "../../../../core-model/dashboard/DashboardWidgetSettings";
+
+export abstract class WidgetConfig {
+
+    abstract getConfig(): DashboardWidgetSettings;
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts b/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts
index 308a45c..307b404 100644
--- a/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/base/base-widget.ts
@@ -6,22 +6,29 @@ import {DashboardWidget} from "../../../../core-model/dashboard/DashboardWidget"
 import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-extractor";
 import {RxStompService} from "@stomp/ng2-stompjs";
 import {Message} from "@stomp/stompjs";
+import {Subscription} from "rxjs";
 
 export abstract class BaseStreamPipesWidget {
 
     @Input() widget: DashboardItem;
     @Input() widgetConfig: DashboardWidget;
 
+    subscription: Subscription;
+
     protected constructor(private rxStompService: RxStompService) {
     }
 
     ngOnInit(): void {
-        this.extractConfig(new StaticPropertyExtractor(this.widgetConfig.dashboardWidgetSettings.requiredSchema, this.widgetConfig.dashboardWidgetSettings.config));
-        this.rxStompService.watch("/topic/" +this.widgetConfig.dashboardWidgetDataConfig.topic).subscribe((message: Message) => {
+        this.extractConfig(new StaticPropertyExtractor(this.widgetConfig.dashboardWidgetDataConfig.schema, this.widgetConfig.dashboardWidgetSettings.config));
+        this.subscription = this.rxStompService.watch("/topic/" +this.widgetConfig.dashboardWidgetDataConfig.topic).subscribe((message: Message) => {
             this.onEvent(JSON.parse(message.body));
         });
     }
 
+    ngOnDestroy(): void {
+        this.subscription.unsubscribe();
+    }
+
     protected abstract extractConfig(extractor: StaticPropertyExtractor);
 
     protected abstract onEvent(event: any);
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts b/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts
index f07a85c..4ee1528 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts
@@ -2,23 +2,24 @@ import {WidgetConfigBuilder} from "../../../registry/widget-config-builder";
 import {SchemaRequirementsBuilder} from "../../../sdk/schema-requirements-builder";
 import {EpRequirements} from "../../../sdk/ep-requirements";
 import {DashboardWidgetSettings} from "../../../../core-model/dashboard/DashboardWidgetSettings";
+import {WidgetConfig} from "../base/base-config";
 
-export class NumberConfig {
+export class NumberConfig extends WidgetConfig {
 
-    static TITLE_KEY: string = "hi";
-    static NUMBER_MAPPING_KEY: string = "number-mapping";
+    static readonly TITLE_KEY: string = "hi";
+    static readonly NUMBER_MAPPING_KEY: string = "number-mapping";
 
     constructor() {
-
+        super();
     }
 
-    static getConfig(): DashboardWidgetSettings {
+    getConfig(): DashboardWidgetSettings {
         return WidgetConfigBuilder.create("number", "number")
             .requiredSchema(SchemaRequirementsBuilder
                 .create()
-                .requiredPropertyWithUnaryMapping(this.TITLE_KEY, "Select property", "", EpRequirements.numberReq())
+                .requiredPropertyWithUnaryMapping(NumberConfig.NUMBER_MAPPING_KEY, "Select property", "", EpRequirements.numberReq())
                 .build())
-            .requiredTextParameter(this.NUMBER_MAPPING_KEY, "hi", "hi")
+            .requiredTextParameter(NumberConfig.TITLE_KEY, "hi", "hi")
             .build();
     }
 
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css
index e2f59c9..154fb78 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css
@@ -1,9 +1,17 @@
 .circleNumber {
     width:100%;
     height: 100%;
-    font-size: 30px;
     color: #fff;
-    line-height: 150px;
     text-align: center;
     left: 50%;
+    display:inline-grid;
+    align-content: center;
+}
+
+.numberTitle {
+    font-size:20px;
+}
+
+.numberItem {
+    font-size:30px;
 }
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts
index 91f7aa2..36f08a0 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts
@@ -1,4 +1,4 @@
-import {Component, Input, OnInit} from "@angular/core";
+import {Component, Input, OnDestroy, OnInit} from "@angular/core";
 import {RxStompService} from "@stomp/ng2-stompjs";
 import {BaseStreamPipesWidget} from "../base/base-widget";
 import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-extractor";
@@ -9,7 +9,7 @@ import {NumberConfig} from "./number-config.component";
     templateUrl: './number-viz.component.html',
     styleUrls: ['./number-viz.component.css']
 })
-export class NumberVizComponent extends BaseStreamPipesWidget implements OnInit {
+export class NumberVizComponent extends BaseStreamPipesWidget implements OnInit, OnDestroy {
 
     item: any;
     title: string;
@@ -25,6 +25,10 @@ export class NumberVizComponent extends BaseStreamPipesWidget implements OnInit
         super.ngOnInit();
     }
 
+    ngOnDestroy(): void {
+        super.ngOnDestroy();
+    }
+
     extractConfig(extractor: StaticPropertyExtractor) {
         this.title = extractor.singleValueParameter(NumberConfig.TITLE_KEY);
         this.selectedProperty = extractor.mappingPropertyValue(NumberConfig.NUMBER_MAPPING_KEY);
@@ -35,8 +39,6 @@ export class NumberVizComponent extends BaseStreamPipesWidget implements OnInit
     }
 
     protected onEvent(event: any) {
-        console.log(event);
-        console.log(this.selectedProperty);
         this.item = event[this.selectedProperty];
     }
 
diff --git a/ui/src/app/dashboard-v2/dialogs/add-widget/add-visualization-dialog.component.ts b/ui/src/app/dashboard-v2/dialogs/add-widget/add-visualization-dialog.component.ts
index 1ecd4e2..9c7b1c8 100644
--- a/ui/src/app/dashboard-v2/dialogs/add-widget/add-visualization-dialog.component.ts
+++ b/ui/src/app/dashboard-v2/dialogs/add-widget/add-visualization-dialog.component.ts
@@ -74,7 +74,7 @@ export class AddVisualizationDialogComponent {
         this.dashboardService.getVisualizablePipelines().subscribe(visualizations => {
             this.visualizablePipelines = visualizations;
         });
-        this.availableWidgets = WidgetRegistry.getAvailableWidgets();
+        this.availableWidgets = WidgetRegistry.getAvailableWidgetTemplates();
     }
 
     onCancel(): void {
@@ -129,7 +129,6 @@ export class AddVisualizationDialogComponent {
             this.page = 'configure-widget';
         } else {
             let configuredWidget: DashboardWidget = new DashboardWidget();
-            configuredWidget._id = "asd";
             configuredWidget.dashboardWidgetSettings = this.selectedWidget;
             configuredWidget.dashboardWidgetDataConfig = this.selectedPipeline;
             this.dashboardService.saveWidget(configuredWidget).subscribe(response => {
diff --git a/ui/src/app/dashboard-v2/models/dashboard.model.ts b/ui/src/app/dashboard-v2/models/dashboard.model.ts
index 37ba299..65aaa96 100644
--- a/ui/src/app/dashboard-v2/models/dashboard.model.ts
+++ b/ui/src/app/dashboard-v2/models/dashboard.model.ts
@@ -4,6 +4,7 @@ export interface DashboardConfig extends GridsterConfig {}
 
 export interface DashboardItem extends GridsterItem {
     widgetId: string;
+    id: string;
 }
 
 export interface Dashboard {
diff --git a/ui/src/app/dashboard-v2/registry/widget-registry.ts b/ui/src/app/dashboard-v2/registry/widget-registry.ts
index ae62523..be6355e 100644
--- a/ui/src/app/dashboard-v2/registry/widget-registry.ts
+++ b/ui/src/app/dashboard-v2/registry/widget-registry.ts
@@ -1,11 +1,14 @@
 import {NumberConfig} from "../components/widgets/number/number-config.component";
 import {DashboardWidgetSettings} from "../../core-model/dashboard/DashboardWidgetSettings";
+import {WidgetConfig} from "../components/widgets/base/base-config";
 
 export class WidgetRegistry {
 
-    private static availableWidgets: Array<DashboardWidgetSettings> = [NumberConfig.getConfig()];
+    private static availableWidgets: Array<WidgetConfig> = [new NumberConfig()];
 
-    static getAvailableWidgets(): Array<DashboardWidgetSettings> {
-        return this.availableWidgets;
+    static getAvailableWidgetTemplates(): Array<DashboardWidgetSettings> {
+        let widgetTemplates = new Array<DashboardWidgetSettings>();
+        this.availableWidgets.forEach(widget => widgetTemplates.push(widget.getConfig()));
+        return widgetTemplates;
     }
 }
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts b/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts
index 3789712..37d68a4 100644
--- a/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts
+++ b/ui/src/app/dashboard-v2/sdk/extractor/static-property-extractor.ts
@@ -21,7 +21,7 @@ export class StaticPropertyExtractor {
     }
 
     getStaticPropertyByName(internalId: string): StaticProperty {
-        return this.staticProperties.find(sp => sp.internalName == internalId);
+        return this.staticProperties.find(sp => (sp.internalName == internalId));
     }
 
 
diff --git a/ui/src/app/dashboard-v2/services/dashboard.service.ts b/ui/src/app/dashboard-v2/services/dashboard.service.ts
index da0849e..3e1b05e 100644
--- a/ui/src/app/dashboard-v2/services/dashboard.service.ts
+++ b/ui/src/app/dashboard-v2/services/dashboard.service.ts
@@ -54,8 +54,10 @@ export class DashboardService {
         });
     }
 
-    updateDashboard(dashboard: Dashboard): Observable<any> {
-        return this.http.put(this.dashboardUrl + "/" +dashboard._id, dashboard);
+    updateDashboard(dashboard: Dashboard): Observable<Dashboard> {
+        return this.http.put(this.dashboardUrl + "/" +dashboard._id, dashboard).map(data => {
+            return data as Dashboard;
+        });
     }
 
     deleteDashboard(dashboard: Dashboard): Observable<any> {