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/12 08:56:44 UTC

[incubator-streampipes] branch new_dashboard updated (b1397d6 -> 7077056)

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

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


    from b1397d6  STREAMPIPES-58: Add support for multiple dashboards
     new 202c5f4  STREAMPIPES-58: Persist dashboard layout changes
     new 0f44dee  Improve editing of dashboards, display name and description
     new a1c3f66  Dashboard items can be resized
     new 3888341  STREAMPIPES-73: Add ColorPickerStaticProperty
     new 9940f60  STREAMPIPES-77: Add support for mapping properties in UI
     new 7077056  STREAMPIPES-77: Add support for mapping properties in UI

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../model/dashboard/DashboardModel.java            |  9 +++
 .../ColorPickerStaticProperty.java}                | 39 +++++-----
 .../model/staticproperty/StaticPropertyType.java   |  1 +
 .../jsonld/CustomAnnotationProvider.java           |  2 +
 .../apache/streampipes/vocabulary/StreamPipes.java |  2 +
 ui/package.json                                    |  2 +-
 ui/src/app/connect/connect.module.ts               |  4 +
 .../app/connect/model/ColorPickerStaticProperty.ts | 15 ++++
 ui/src/app/connect/model/FreeTextStaticProperty.ts |  3 +
 ui/src/app/connect/model/MappingPropertyNary.ts    |  4 +-
 .../static-color-picker.component.css}             |  0
 .../static-color-picker.component.html}            | 19 +++--
 .../static-color-picker.component.ts               | 51 ++++++++++++
 .../static-mapping-nary.component.html             | 16 ++--
 .../static-mapping-nary.component.ts               | 48 ++++++++----
 .../static-mapping-unary.component.ts              | 32 ++++----
 .../static-mapping/static-mapping.ts               | 20 +++++
 .../static-property-util.service.ts                | 13 +++-
 .../static-property.component.html                 |  6 +-
 .../static-properties/static-property.component.ts |  5 ++
 .../components/grid/dashboard-grid.component.css   |  8 ++
 .../components/grid/dashboard-grid.component.html  | 11 +++
 .../components/grid/dashboard-grid.component.ts    | 50 ++++++++++++
 .../overview/dashboard-overview.component.html     | 29 ++++++-
 .../overview/dashboard-overview.component.ts       | 11 ++-
 .../components/panel/dashboard-panel.component.css |  8 +-
 .../panel/dashboard-panel.component.html           | 15 +---
 .../components/panel/dashboard-panel.component.ts  | 32 ++++----
 .../widget/dashboard-widget.component.css          |  1 +
 .../widget/dashboard-widget.component.html         | 12 ++-
 .../widget/dashboard-widget.component.ts           |  7 +-
 .../components/widgets/base/base-widget.ts         |  4 +-
 .../components/widgets/line/line-config.ts         | 28 +++++++
 .../widgets/line/line-widget.component.css         | 11 +++
 .../widgets/line/line-widget.component.html        | 23 ++++++
 .../widgets/line/line-widget.component.ts          | 90 ++++++++++++++++++++++
 ...number-config.component.ts => number-config.ts} |  6 +-
 ...z.component.css => number-widget.component.css} |  3 +-
 ...component.html => number-widget.component.html} |  2 +-
 ...viz.component.ts => number-widget.component.ts} | 11 +--
 .../table-config.ts}                               | 16 ++--
 .../widgets/table/table-widget.component.css}      |  0
 .../widgets/table/table-widget.component.html      | 11 +++
 .../widgets/table/table-widget.component.ts        | 54 +++++++++++++
 ui/src/app/dashboard-v2/dashboard.component.css    |  3 +
 ui/src/app/dashboard-v2/dashboard.component.html   | 26 +++++--
 ui/src/app/dashboard-v2/dashboard.component.ts     | 11 +++
 ui/src/app/dashboard-v2/dashboard.module.ts        | 16 +++-
 .../add-visualization-dialog.component.ts          |  3 +-
 .../edit-dashboard-dialog.component.html           |  1 +
 ui/src/app/dashboard-v2/models/dashboard.model.ts  |  1 +
 .../app/dashboard-v2/models/gridster-info.model.ts |  6 ++
 .../app/dashboard-v2/models/multi-series.model.ts  | 11 +++
 .../app/dashboard-v2/models/widget-data.model.ts   |  6 --
 .../dashboard-v2/registry/widget-config-builder.ts | 39 +++++++++-
 .../app/dashboard-v2/registry/widget-registry.ts   | 10 ++-
 ui/src/app/dashboard-v2/sdk/ep-requirements.ts     |  8 ++
 .../sdk/extractor/static-property-extractor.ts     | 24 ++++++
 .../sdk/schema-requirements-builder.ts             | 24 ++++--
 ui/src/app/dashboard-v2/services/resize.service.ts | 13 ++++
 .../platform-services/tsonld-serializer.service.ts |  4 +
 61 files changed, 772 insertions(+), 168 deletions(-)
 copy streampipes-model/src/main/java/org/apache/streampipes/model/{connect/rules/Schema/CreateNestedRuleDescription.java => staticproperty/ColorPickerStaticProperty.java} (56%)
 create mode 100644 ui/src/app/connect/model/ColorPickerStaticProperty.ts
 copy ui/src/app/{dashboard-v2/dashboard.component.css => connect/static-properties/static-color-picker/static-color-picker.component.css} (100%)
 copy ui/src/app/connect/static-properties/{static-url-input/static-url-input.component.html => static-color-picker/static-color-picker.component.html} (62%)
 create mode 100644 ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
 create mode 100644 ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
 create mode 100644 ui/src/app/dashboard-v2/components/widgets/line/line-config.ts
 create mode 100644 ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.css
 create mode 100644 ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.html
 create mode 100644 ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.ts
 copy ui/src/app/dashboard-v2/components/widgets/number/{number-config.component.ts => number-config.ts} (75%)
 rename ui/src/app/dashboard-v2/components/widgets/number/{number-viz.component.css => number-widget.component.css} (83%)
 rename ui/src/app/dashboard-v2/components/widgets/number/{number-viz.component.html => number-widget.component.html} (97%)
 rename ui/src/app/dashboard-v2/components/widgets/number/{number-viz.component.ts => number-widget.component.ts} (74%)
 rename ui/src/app/dashboard-v2/components/widgets/{number/number-config.component.ts => table/table-config.ts} (56%)
 copy ui/src/app/dashboard-v2/{dashboard.component.css => components/widgets/table/table-widget.component.css} (100%)
 create mode 100644 ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.html
 create mode 100644 ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.ts
 create mode 100644 ui/src/app/dashboard-v2/models/gridster-info.model.ts
 create mode 100644 ui/src/app/dashboard-v2/models/multi-series.model.ts
 delete mode 100644 ui/src/app/dashboard-v2/models/widget-data.model.ts
 create mode 100644 ui/src/app/dashboard-v2/services/resize.service.ts


[incubator-streampipes] 04/06: STREAMPIPES-73: Add ColorPickerStaticProperty

Posted by ri...@apache.org.
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

commit 388834164c318006b7c38ffbb7ff87344468f71b
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Tue Feb 11 23:50:21 2020 +0100

    STREAMPIPES-73: Add ColorPickerStaticProperty
---
 .../staticproperty/ColorPickerStaticProperty.java  | 53 ++++++++++++++++++++++
 .../model/staticproperty/StaticPropertyType.java   |  1 +
 .../jsonld/CustomAnnotationProvider.java           |  2 +
 .../apache/streampipes/vocabulary/StreamPipes.java |  2 +
 ui/src/app/connect/connect.module.ts               |  4 ++
 .../app/connect/model/ColorPickerStaticProperty.ts | 15 ++++++
 .../static-color-picker.component.css              |  0
 .../static-color-picker.component.html             | 30 ++++++++++++
 .../static-color-picker.component.ts               | 51 +++++++++++++++++++++
 .../static-property-util.service.ts                | 10 ++++
 .../static-property.component.html                 |  4 ++
 .../static-properties/static-property.component.ts |  5 ++
 .../components/widgets/number/number-config.ts     |  6 ++-
 .../widgets/number/number-widget.component.ts      |  1 +
 .../dashboard-v2/registry/widget-config-builder.ts | 10 ++++
 .../sdk/extractor/static-property-extractor.ts     |  6 +++
 .../platform-services/tsonld-serializer.service.ts |  2 +
 17 files changed, 200 insertions(+), 2 deletions(-)

diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/ColorPickerStaticProperty.java b/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/ColorPickerStaticProperty.java
new file mode 100644
index 0000000..9286e91
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/ColorPickerStaticProperty.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.streampipes.model.staticproperty;
+
+import org.apache.streampipes.vocabulary.StreamPipes;
+import org.streampipes.empire.annotations.RdfProperty;
+import org.streampipes.empire.annotations.RdfsClass;
+
+import javax.persistence.Entity;
+
+@RdfsClass(StreamPipes.COLOR_PICKER_STATIC_PROPERTY)
+@Entity
+public class ColorPickerStaticProperty extends StaticProperty {
+
+  @RdfProperty(StreamPipes.SELECTED_COLOR)
+  private String selectedColor;
+
+  public ColorPickerStaticProperty() {
+    super(StaticPropertyType.ColorPickerStaticProperty);
+  }
+
+  public ColorPickerStaticProperty(ColorPickerStaticProperty other) {
+    super(other);
+    this.selectedColor = other.getSelectedColor();
+  }
+
+  public ColorPickerStaticProperty(String internalName, String label, String description) {
+    super(StaticPropertyType.ColorPickerStaticProperty, internalName, label, description);
+  }
+
+  public String getSelectedColor() {
+    return selectedColor;
+  }
+
+  public void setSelectedColor(String selectedColor) {
+    this.selectedColor = selectedColor;
+  }
+}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/StaticPropertyType.java b/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/StaticPropertyType.java
index 9018b76..1542bfe 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/StaticPropertyType.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/staticproperty/StaticPropertyType.java
@@ -21,6 +21,7 @@ package org.apache.streampipes.model.staticproperty;
 public enum StaticPropertyType {
     AnyStaticProperty,
     CollectionStaticProperty,
+    ColorPickerStaticProperty,
     DomainStaticProperty,
     FreeTextStaticProperty,
     FileStaticProperty,
diff --git a/streampipes-serializers/src/main/java/org/apache/streampipes/serializers/jsonld/CustomAnnotationProvider.java b/streampipes-serializers/src/main/java/org/apache/streampipes/serializers/jsonld/CustomAnnotationProvider.java
index b774052..0da8817 100644
--- a/streampipes-serializers/src/main/java/org/apache/streampipes/serializers/jsonld/CustomAnnotationProvider.java
+++ b/streampipes-serializers/src/main/java/org/apache/streampipes/serializers/jsonld/CustomAnnotationProvider.java
@@ -95,6 +95,7 @@ import org.apache.streampipes.model.schema.EventSchema;
 import org.apache.streampipes.model.schema.QuantitativeValue;
 import org.apache.streampipes.model.staticproperty.AnyStaticProperty;
 import org.apache.streampipes.model.staticproperty.CollectionStaticProperty;
+import org.apache.streampipes.model.staticproperty.ColorPickerStaticProperty;
 import org.apache.streampipes.model.staticproperty.DomainStaticProperty;
 import org.apache.streampipes.model.staticproperty.FileStaticProperty;
 import org.apache.streampipes.model.staticproperty.FreeTextStaticProperty;
@@ -145,6 +146,7 @@ public class CustomAnnotationProvider implements EmpireAnnotationProvider {
   private List<Class<?>> getAnnotatedClasses() {
     return Arrays.asList(
             Accuracy.class,
+            ColorPickerStaticProperty.class,
             CustomOutputStrategy.class,
             DataSinkDescription.class,
             DataProcessorInvocation.class,
diff --git a/streampipes-vocabulary/src/main/java/org/apache/streampipes/vocabulary/StreamPipes.java b/streampipes-vocabulary/src/main/java/org/apache/streampipes/vocabulary/StreamPipes.java
index 70dac11..5fed7b9 100644
--- a/streampipes-vocabulary/src/main/java/org/apache/streampipes/vocabulary/StreamPipes.java
+++ b/streampipes-vocabulary/src/main/java/org/apache/streampipes/vocabulary/StreamPipes.java
@@ -374,4 +374,6 @@ public class StreamPipes {
   public static final String CONTAINS_ELEMENTS = NS + "containsElement";
   public static final String HAS_DASHBOARD_WIDGET_ID = NS + "hasDashboardWidgetId";
   public static final String DASHBOARD_WIDGET_DATA_CONFIG = NS + "DashboardWidgetDataConfig" ;
+  public static final String COLOR_PICKER_STATIC_PROPERTY = NS + "ColorPickerStaticProperty";
+  public static final String SELECTED_COLOR = NS + "hasSelectedColor";
 }
diff --git a/ui/src/app/connect/connect.module.ts b/ui/src/app/connect/connect.module.ts
index df4b923..22030c3 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -94,6 +94,8 @@ import { TreeModule } from 'angular-tree-component';
 import { EventSchemaPreviewComponent } from './schema-editor/event-schema-preview/event-schema-preview.component';
 import {EventPropertyRowComponent} from "./schema-editor/event-property-row/event-property-row.component";
 import {PropertySelectorService} from "../services/property-selector.service";
+import {StaticColorPickerComponent} from "./static-properties/static-color-picker/static-color-picker.component";
+import {ColorPickerModule} from "ngx-color-picker";
 
 
 @NgModule({
@@ -111,6 +113,7 @@ import {PropertySelectorService} from "../services/property-selector.service";
         MatFormFieldModule,
         PlatformServicesModule,
         TreeModule.forRoot(),
+        ColorPickerModule
     ],
     exports: [
         StaticPropertyComponent,
@@ -156,6 +159,7 @@ import {PropertySelectorService} from "../services/property-selector.service";
         StaticGroupComponent,
         StaticAlternativesComponent,
         StaticCollectionComponent,
+        StaticColorPickerComponent
     ],
     providers: [
         RestService,
diff --git a/ui/src/app/connect/model/ColorPickerStaticProperty.ts b/ui/src/app/connect/model/ColorPickerStaticProperty.ts
new file mode 100644
index 0000000..a9e8376
--- /dev/null
+++ b/ui/src/app/connect/model/ColorPickerStaticProperty.ts
@@ -0,0 +1,15 @@
+import {RdfsClass} from "../../platform-services/tsonld/RdfsClass";
+import {StaticProperty} from "./StaticProperty";
+import {RdfProperty} from "../../platform-services/tsonld/RdfsProperty";
+
+@RdfsClass('sp:ColorPickerStaticProperty')
+export class ColorPickerStaticProperty extends StaticProperty {
+
+    @RdfProperty('sp:hasSelectedColor')
+    public selectedColor: string;
+
+    constructor() {
+        super();
+    }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.css b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.html b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.html
new file mode 100644
index 0000000..c4dffe7
--- /dev/null
+++ b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.html
@@ -0,0 +1,30 @@
+<!--
+  ~ 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.
+  ~
+  -->
+Color
+<div id="formWrapper">
+    <form [formGroup]="colorPickerForm">
+        <mat-form-field>
+            <input matInput id="{{ 'input-' + staticProperty.label.toLowerCase() }}"
+                   [(colorPicker)]="staticPropertyUtil.asColorPickerStaticProperty(staticProperty).selectedColor"
+                   formControlName="colorPickerStaticProperty"
+                   [style.background]="staticPropertyUtil.asColorPickerStaticProperty(staticProperty).selectedColor" required
+                   (blur)="emitUpdate()"/>
+        </mat-form-field>
+    </form>
+</div>
+
diff --git a/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
new file mode 100644
index 0000000..597774d
--- /dev/null
+++ b/ui/src/app/connect/static-properties/static-color-picker/static-color-picker.component.ts
@@ -0,0 +1,51 @@
+import {Component, EventEmitter, Input, OnInit, Output} from "@angular/core";
+import {ConfigurationInfo} from "../../model/message/ConfigurationInfo";
+import {StaticProperty} from "../../model/StaticProperty";
+import {StaticPropertyUtilService} from "../static-property-util.service";
+import {FormControl, FormGroup, Validators} from "@angular/forms";
+
+@Component({
+    selector: 'app-static-color-picker',
+    templateUrl: './static-color-picker.component.html',
+    styleUrls: ['./static-color-picker.component.css']
+})
+export class StaticColorPickerComponent implements OnInit {
+
+    constructor(private staticPropertyUtil: StaticPropertyUtilService){
+
+    }
+
+    @Output() updateEmitter: EventEmitter<ConfigurationInfo> = new EventEmitter();
+
+    @Input() staticProperty: StaticProperty;
+    @Output() inputEmitter: EventEmitter<any> = new EventEmitter<any>();
+
+    private inputValue: String;
+    private hasInput: Boolean;
+    private colorPickerForm: FormGroup;
+
+    ngOnInit() {
+        this.colorPickerForm = new FormGroup({
+            'colorPickerStaticProperty': new FormControl(this.inputValue, [
+                Validators.required
+            ]),
+        })
+    }
+
+    valueChange(inputValue) {
+        this.inputValue = inputValue;
+        if (inputValue == "" || !inputValue) {
+            this.hasInput = false;
+        } else {
+            this.hasInput = true;
+        }
+
+        this.inputEmitter.emit(this.hasInput);
+
+    }
+
+    emitUpdate() {
+        this.updateEmitter.emit(new ConfigurationInfo(this.staticProperty.internalName, this.staticPropertyUtil.asColorPickerStaticProperty(this.staticProperty).selectedColor && this.staticPropertyUtil.asColorPickerStaticProperty(this.staticProperty).selectedColor !== ""));
+    }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-property-util.service.ts b/ui/src/app/connect/static-properties/static-property-util.service.ts
index 69d6f62..325e5d2 100644
--- a/ui/src/app/connect/static-properties/static-property-util.service.ts
+++ b/ui/src/app/connect/static-properties/static-property-util.service.ts
@@ -33,6 +33,7 @@ import { AlternativesStaticProperty } from "../model/AlternativesStaticProperty"
 import { AlternativeStaticProperty } from "../model/AlternativeStaticProperty";
 import { Option } from "../model/Option";
 import { URI } from "../model/URI";
+import {ColorPickerStaticProperty} from "../model/ColorPickerStaticProperty";
 
 
 @Injectable()
@@ -73,6 +74,11 @@ export class StaticPropertyUtilService{
             clone.value = val.value;
             clone.isEncrypted = val.isEncrypted;
         }
+        else if (val instanceof ColorPickerStaticProperty) {
+            clone = new ColorPickerStaticProperty();
+            clone.id = id;
+            clone.selectedProperty = val.selectedColor;
+        }
         else if (val instanceof GroupStaticProperty) {
             clone = new GroupStaticProperty(id);
             clone.staticProperties = val.staticProperties.map(elem => this.clone(elem));
@@ -152,6 +158,10 @@ export class StaticPropertyUtilService{
         return <FreeTextStaticProperty> val;
     }
 
+    public asColorPickerStaticProperty(val: StaticProperty): ColorPickerStaticProperty {
+        return <ColorPickerStaticProperty> val;
+    }
+
     public asSecretStaticProperty(val: StaticProperty): SecretStaticProperty {
         return <SecretStaticProperty> val;
     }
diff --git a/ui/src/app/connect/static-properties/static-property.component.html b/ui/src/app/connect/static-properties/static-property.component.html
index c4e276b..26493db 100644
--- a/ui/src/app/connect/static-properties/static-property.component.html
+++ b/ui/src/app/connect/static-properties/static-property.component.html
@@ -41,6 +41,10 @@
     (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty" [adapterId]="adapterId">
 </app-static-file-input>
 
+<app-static-color-picker *ngIf="isColorPickerStaticProperty(staticProperty)"
+                       (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty">
+</app-static-color-picker>
+
 <app-static-runtime-resolvable-any-input *ngIf="isRuntimeResolvableAnyStaticProperty(staticProperty)"
                       (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty"></app-static-runtime-resolvable-any-input>
 
diff --git a/ui/src/app/connect/static-properties/static-property.component.ts b/ui/src/app/connect/static-properties/static-property.component.ts
index 568875c..a8e9bd8 100644
--- a/ui/src/app/connect/static-properties/static-property.component.ts
+++ b/ui/src/app/connect/static-properties/static-property.component.ts
@@ -36,6 +36,7 @@ import {SecretStaticProperty} from "../model/SecretStaticProperty";
 import {AlternativesStaticProperty} from '../model/AlternativesStaticProperty';
 import {GroupStaticProperty} from '../model/GroupStaticProperty';
 import { CollectionStaticProperty } from "../model/CollectionStaticProperty";
+import {ColorPickerStaticProperty} from "../model/ColorPickerStaticProperty";
 
 @Component({
   selector: 'app-static-property',
@@ -128,6 +129,10 @@ export class StaticPropertyComponent implements OnInit {
     return val instanceof SecretStaticProperty;
   }
 
+  isColorPickerStaticProperty(val) {
+    return val instanceof ColorPickerStaticProperty;
+  }
+
   isRuntimeResolvableAnyStaticProperty(val) {
     return val instanceof RuntimeResolvableAnyStaticProperty;
   }
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-config.ts b/ui/src/app/dashboard-v2/components/widgets/number/number-config.ts
index 4ee1528..1fb3788 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-config.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-config.ts
@@ -6,8 +6,9 @@ import {WidgetConfig} from "../base/base-config";
 
 export class NumberConfig extends WidgetConfig {
 
-    static readonly TITLE_KEY: string = "hi";
+    static readonly TITLE_KEY: string = "title-key";
     static readonly NUMBER_MAPPING_KEY: string = "number-mapping";
+    static readonly COLOR_KEY: string = "color-key";
 
     constructor() {
         super();
@@ -19,7 +20,8 @@ export class NumberConfig extends WidgetConfig {
                 .create()
                 .requiredPropertyWithUnaryMapping(NumberConfig.NUMBER_MAPPING_KEY, "Select property", "", EpRequirements.numberReq())
                 .build())
-            .requiredTextParameter(NumberConfig.TITLE_KEY, "hi", "hi")
+            .requiredTextParameter(NumberConfig.TITLE_KEY, "Title", "The title")
+            .requiredColorParameter(NumberConfig.COLOR_KEY, "Background color", "The background color")
             .build();
     }
 
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts
index 28c27f3..1c127c1 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts
@@ -30,6 +30,7 @@ export class NumberWidgetComponent extends BaseStreamPipesWidget implements OnIn
     }
 
     extractConfig(extractor: StaticPropertyExtractor) {
+        this.color = extractor.selectedColor(NumberConfig.COLOR_KEY);
         this.title = extractor.singleValueParameter(NumberConfig.TITLE_KEY);
         this.selectedProperty = extractor.mappingPropertyValue(NumberConfig.NUMBER_MAPPING_KEY);
     }
diff --git a/ui/src/app/dashboard-v2/registry/widget-config-builder.ts b/ui/src/app/dashboard-v2/registry/widget-config-builder.ts
index 18f5583..bce7475 100644
--- a/ui/src/app/dashboard-v2/registry/widget-config-builder.ts
+++ b/ui/src/app/dashboard-v2/registry/widget-config-builder.ts
@@ -4,6 +4,7 @@ import {EventSchema} from "../../connect/schema-editor/model/EventSchema";
 import {DashboardWidgetSettings} from "../../core-model/dashboard/DashboardWidgetSettings";
 import {Vocabulary} from "../sdk/model/vocabulary";
 import {Datatypes} from "../sdk/model/datatypes";
+import {ColorPickerStaticProperty} from "../../connect/model/ColorPickerStaticProperty";
 
 export class WidgetConfigBuilder {
 
@@ -26,6 +27,15 @@ export class WidgetConfigBuilder {
         return this;
     }
 
+    requiredColorParameter(id: string, label: string, description: string): WidgetConfigBuilder {
+        let csp = new ColorPickerStaticProperty();
+        csp.internalName = id;
+        csp.label = label;
+        csp.description = description;
+        this.widget.config.push(csp);
+        return this;
+    }
+
     requiredIntegerParameter(id: string, label: string, description: string): WidgetConfigBuilder {
         let fst: FreeTextStaticProperty = this.prepareStaticProperty(id, label, description, Datatypes.Integer.toUri())
         this.widget.config.push(fst);
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 f752fbc..aa55a89 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
@@ -2,6 +2,7 @@ import {EventSchema} from "../../../connect/schema-editor/model/EventSchema";
 import {StaticProperty} from "../../../connect/model/StaticProperty";
 import {MappingPropertyUnary} from "../../../connect/model/MappingPropertyUnary";
 import {FreeTextStaticProperty} from "../../../connect/model/FreeTextStaticProperty";
+import {ColorPickerStaticProperty} from "../../../connect/model/ColorPickerStaticProperty";
 
 export class StaticPropertyExtractor {
 
@@ -20,6 +21,11 @@ export class StaticPropertyExtractor {
         return sp.value;
     }
 
+    selectedColor(internalId: string): any {
+        let sp: ColorPickerStaticProperty = this.getStaticPropertyByName(internalId) as ColorPickerStaticProperty;
+        return sp.selectedColor;
+    }
+
     stringParameter(internalId: string): string {
         return this.singleValueParameter(internalId) as string;
     }
diff --git a/ui/src/app/platform-services/tsonld-serializer.service.ts b/ui/src/app/platform-services/tsonld-serializer.service.ts
index aedc2ed..ee66a5c 100644
--- a/ui/src/app/platform-services/tsonld-serializer.service.ts
+++ b/ui/src/app/platform-services/tsonld-serializer.service.ts
@@ -96,6 +96,7 @@ import {VisualizablePipeline} from "../core-model/dashboard/VisualizablePipeline
 import {DashboardWidget} from "../core-model/dashboard/DashboardWidget";
 import {DashboardWidgetDataConfig} from "../core-model/dashboard/DashboardWidgetDataConfig";
 import {DashboardWidgetSettings} from "../core-model/dashboard/DashboardWidgetSettings";
+import {ColorPickerStaticProperty} from "../connect/model/ColorPickerStaticProperty";
 
 
 @Injectable()
@@ -188,6 +189,7 @@ export class TsonLdSerializerService {
         tsonld.addClassMapping(DashboardWidgetSettings);
 
         tsonld.addClassMapping(VisualizablePipeline);
+        tsonld.addClassMapping(ColorPickerStaticProperty);
 
         tsonld.addContext('sp', 'https://streampipes.org/vocabulary/v1/');
         tsonld.addContext('spi', 'urn:streampipes.org:spi:');


[incubator-streampipes] 05/06: STREAMPIPES-77: Add support for mapping properties in UI

Posted by ri...@apache.org.
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

commit 9940f602b20414d79b3c4ad0f58a9aaac5ef9769
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Wed Feb 12 09:42:47 2020 +0100

    STREAMPIPES-77: Add support for mapping properties in UI
---
 ui/src/app/connect/static-properties/static-mapping/static-mapping.ts     | 0
 ui/src/app/dashboard-v2/components/widgets/table/table-config.ts          | 0
 .../app/dashboard-v2/components/widgets/table/table-widget.component.css  | 0
 .../app/dashboard-v2/components/widgets/table/table-widget.component.html | 0
 .../app/dashboard-v2/components/widgets/table/table-widget.component.ts   | 0
 5 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts b/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
new file mode 100644
index 0000000..e69de29
diff --git a/ui/src/app/dashboard-v2/components/widgets/table/table-config.ts b/ui/src/app/dashboard-v2/components/widgets/table/table-config.ts
new file mode 100644
index 0000000..e69de29
diff --git a/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.css b/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.html b/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.html
new file mode 100644
index 0000000..e69de29
diff --git a/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.ts b/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.ts
new file mode 100644
index 0000000..e69de29


[incubator-streampipes] 03/06: Dashboard items can be resized

Posted by ri...@apache.org.
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

commit a1c3f66d4ba21df544a632e0aefcf17ba671760b
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Tue Feb 11 22:47:54 2020 +0100

    Dashboard items can be resized
---
 ui/package.json                                    |  2 +-
 ui/src/app/connect/model/FreeTextStaticProperty.ts |  3 +
 .../components/grid/dashboard-grid.component.html  |  2 +-
 .../components/grid/dashboard-grid.component.ts    | 38 ++++++++-
 .../overview/dashboard-overview.component.html     |  1 +
 .../panel/dashboard-panel.component.html           |  2 +-
 .../components/panel/dashboard-panel.component.ts  | 31 ++------
 .../widget/dashboard-widget.component.css          |  1 +
 .../widget/dashboard-widget.component.html         |  8 +-
 .../widget/dashboard-widget.component.ts           |  7 +-
 .../components/widgets/base/base-widget.ts         |  2 +
 .../components/widgets/line/line-config.ts         | 28 +++++++
 .../widgets/line/line-widget.component.css         | 11 +++
 .../widgets/line/line-widget.component.html        | 23 ++++++
 .../widgets/line/line-widget.component.ts          | 90 ++++++++++++++++++++++
 ...number-config.component.ts => number-config.ts} |  0
 ...z.component.css => number-widget.component.css} |  0
 ...component.html => number-widget.component.html} |  2 +-
 ...viz.component.ts => number-widget.component.ts} | 10 +--
 ui/src/app/dashboard-v2/dashboard.module.ts        | 10 ++-
 .../app/dashboard-v2/models/gridster-info.model.ts |  6 ++
 .../app/dashboard-v2/models/multi-series.model.ts  | 11 +++
 .../dashboard-v2/registry/widget-config-builder.ts | 29 ++++++-
 .../app/dashboard-v2/registry/widget-registry.ts   |  8 +-
 ui/src/app/dashboard-v2/sdk/ep-requirements.ts     |  4 +
 .../sdk/extractor/static-property-extractor.ts     |  8 ++
 ui/src/app/dashboard-v2/services/resize.service.ts | 13 ++++
 27 files changed, 302 insertions(+), 48 deletions(-)

diff --git a/ui/package.json b/ui/package.json
index d53dc74..353839a 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -29,7 +29,7 @@
     "@angular/upgrade": "7.2.9",
     "@ngui/datetime-picker": "0.16.2",
     "@stomp/ng2-stompjs": "^7.2.0",
-    "@swimlane/ngx-charts": "13.0.2",
+    "@swimlane/ngx-charts": "^13.0.2",
     "@uirouter/angular-hybrid": "7.0.0",
     "angular": "1.7.7",
     "angular-animate": "1.7.7",
diff --git a/ui/src/app/connect/model/FreeTextStaticProperty.ts b/ui/src/app/connect/model/FreeTextStaticProperty.ts
index 6ac1a48..ca03261 100644
--- a/ui/src/app/connect/model/FreeTextStaticProperty.ts
+++ b/ui/src/app/connect/model/FreeTextStaticProperty.ts
@@ -30,6 +30,9 @@ export class FreeTextStaticProperty extends StaticProperty {
   @RdfProperty('sp:requiredDomainProperty')
   public requiredDomainProperty: string;
 
+  @RdfProperty('sp:requiresDatatype')
+  public requiredDatatype: string;
+
   //TODO find better solution
   public render: boolean;
 
diff --git a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
index dc85ab7..299ed3e 100644
--- a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
+++ b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
@@ -5,7 +5,7 @@
 <gridster [options]="options" [ngClass]="editMode ? 'edit' : ''">
     <ng-container *ngFor="let item of dashboard.widgets">
         <gridster-item [item]="item">
-            <dashboard-widget [widget]="item" [editMode]="editMode"></dashboard-widget>
+            <dashboard-widget [item]="item" [widget]="item" [editMode]="editMode"></dashboard-widget>
         </gridster-item>
     </ng-container>
 </gridster>
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts
index 278f7dd..c1d589b 100644
--- a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts
+++ b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts
@@ -1,18 +1,50 @@
-import {Component, Input, OnInit} from "@angular/core";
+import {AfterViewInit, Component, Input, OnChanges, OnInit, SimpleChanges} from "@angular/core";
 import {Dashboard, DashboardConfig} from "../../models/dashboard.model";
+import {GridsterInfo} from "../../models/gridster-info.model";
+import {ResizeService} from "../../services/resize.service";
+import {GridType} from "angular-gridster2";
 
 @Component({
     selector: 'dashboard-grid',
     templateUrl: './dashboard-grid.component.html',
     styleUrls: ['./dashboard-grid.component.css']
 })
-export class DashboardGridComponent implements OnInit {
+export class DashboardGridComponent implements OnInit, OnChanges {
 
     @Input() editMode: boolean;
     @Input() dashboard: Dashboard;
-    @Input() options: DashboardConfig;
+    options: DashboardConfig;
+
+    constructor(private resizeService: ResizeService) {
+
+    }
 
     ngOnInit(): void {
+        this.options = {
+            disablePushOnDrag: true,
+            draggable: { enabled: this.editMode },
+            gridType: GridType.VerticalFixed,
+            minCols: 8,
+            maxCols: 8,
+            minRows: 4,
+            fixedRowHeight: 100,
+            fixedColWidth: 100,
+            resizable: { enabled: this.editMode },
+            itemResizeCallback: ((item, itemComponent) => {
+                this.resizeService.notify({gridsterItem: item, gridsterItemComponent: itemComponent} as GridsterInfo);
+            }),
+            itemInitCallback: ((item, itemComponent) => {
+                this.resizeService.notify({gridsterItem: item, gridsterItemComponent: itemComponent} as GridsterInfo);
+            })
+        };
     }
 
+    ngOnChanges(changes: SimpleChanges): void {
+        if (changes["editMode"] && this.options) {
+            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/overview/dashboard-overview.component.html b/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html
index 35a2f3a..86a80f4 100644
--- a/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html
+++ b/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html
@@ -30,6 +30,7 @@
             </div>
         </div>
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="sp-blue-border">
+
             <table fxFlex="95" mat-table [dataSource]="dataSource" multiTemplateDataRows>
 
                 <ng-container matColumnDef="name">
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 55448cd..b6c324f 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
@@ -7,5 +7,5 @@
             visualization</button>
     </div>
 
-    <dashboard-grid [editMode]="editMode" [dashboard]="dashboard" [options]="options" class="h-100"></dashboard-grid>
+    <dashboard-grid [editMode]="editMode" [dashboard]="dashboard" class="h-100"></dashboard-grid>
 </div>
\ No newline at end of file
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 96d3216..58d9d72 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
@@ -6,19 +6,22 @@ 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";
+import {GridsterItem} from "angular-gridster2/lib/gridsterItem.interface";
+import {GridsterItemComponentInterface} from "angular-gridster2/lib/gridsterItemComponent.interface";
+import {ResizeService} from "../../services/resize.service";
+import {GridsterInfo} from "../../models/gridster-info.model";
 
 @Component({
     selector: 'dashboard-panel',
     templateUrl: './dashboard-panel.component.html',
     styleUrls: ['./dashboard-panel.component.css']
 })
-export class DashboardPanelComponent implements OnInit, OnChanges {
+export class DashboardPanelComponent implements OnInit {
 
     @Input() dashboard: Dashboard;
     @Input("editMode") editMode: boolean;
     @Output("editModeChange") editModeChange: EventEmitter<boolean> = new EventEmitter();
 
-    public options: DashboardConfig;
     public items: DashboardItem[];
 
     protected subscription: Subscription;
@@ -27,17 +30,7 @@ export class DashboardPanelComponent implements OnInit, OnChanges {
                 public dialog: MatDialog) {}
 
     public ngOnInit() {
-        this.options = {
-            disablePushOnDrag: true,
-            draggable: { enabled: this.editMode },
-            gridType: GridType.VerticalFixed,
-            minCols: 8,
-            maxCols: 8,
-            minRows: 4,
-            fixedRowHeight: 100,
-            fixedColWidth: 100,
-            resizable: { enabled: this.editMode }
-        };
+
     }
 
     addWidget(): void {
@@ -79,17 +72,5 @@ export class DashboardPanelComponent implements OnInit, OnChanges {
         this.editModeChange.emit(!(this.editMode));
     }
 
-    ngOnChanges(changes: SimpleChanges): void {
-        if (changes["editMode"] && this.options) {
-            // if (this.editMode) {
-            //     this.updateDashboard();
-            // }
-            // 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 3627cb9..2e70039 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
@@ -14,6 +14,7 @@
     display: flex;
     flex-flow: column;
     height: 100%;
+    border:0px solid black;
 }
 
 .box .row.content {
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 2f8713e..f1fb0f9 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
@@ -10,11 +10,15 @@
                 </button>
             </div>
         </div>
-        <div class="sp-blue-border h-100 p-0 row content">
+        <div class="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>
+                    <number-widget [gridsterItem]="item" [widget]="widget"
+                                   [widgetConfig]="configuredWidget"></number-widget>
+                </div>
+                <div *ngIf="widget.widgetType === 'line'" class="h-100 p-0">
+                    <line-widget [gridsterItem]="item" [widget]="widget" [widgetConfig]="configuredWidget"></line-widget>
                 </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 08299f1..e88b18a 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
@@ -1,8 +1,12 @@
-import {Component, Input, OnInit} from "@angular/core";
+import {AfterViewInit, Component, Input, OnInit} from "@angular/core";
 import {Dashboard, DashboardItem} from "../../models/dashboard.model";
 import {DashboardService} from "../../services/dashboard.service";
 import {DashboardImageComponent} from "../../../app-transport-monitoring/components/dashboard-image/dashboard-image.component";
 import {DashboardWidget} from "../../../core-model/dashboard/DashboardWidget";
+import {Subject} from "rxjs";
+import {GridsterItem} from "angular-gridster2";
+import {GridsterInfo} from "../../models/gridster-info.model";
+import {ResizeService} from "../../services/resize.service";
 
 @Component({
     selector: 'dashboard-widget',
@@ -13,6 +17,7 @@ export class DashboardWidgetComponent implements OnInit {
 
     @Input() widget: DashboardItem;
     @Input() editMode: boolean;
+    @Input() item: GridsterItem;
 
     widgetLoaded: boolean = false;
     configuredWidget: DashboardWidget;
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 307b404..0dc219a 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
@@ -7,11 +7,13 @@ import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-ex
 import {RxStompService} from "@stomp/ng2-stompjs";
 import {Message} from "@stomp/stompjs";
 import {Subscription} from "rxjs";
+import {GridsterItem} from "angular-gridster2";
 
 export abstract class BaseStreamPipesWidget {
 
     @Input() widget: DashboardItem;
     @Input() widgetConfig: DashboardWidget;
+    @Input() gridsterItem: GridsterItem;
 
     subscription: Subscription;
 
diff --git a/ui/src/app/dashboard-v2/components/widgets/line/line-config.ts b/ui/src/app/dashboard-v2/components/widgets/line/line-config.ts
new file mode 100644
index 0000000..709614b
--- /dev/null
+++ b/ui/src/app/dashboard-v2/components/widgets/line/line-config.ts
@@ -0,0 +1,28 @@
+import {WidgetConfig} from "../base/base-config";
+import {DashboardWidgetSettings} from "../../../../core-model/dashboard/DashboardWidgetSettings";
+import {WidgetConfigBuilder} from "../../../registry/widget-config-builder";
+import {SchemaRequirementsBuilder} from "../../../sdk/schema-requirements-builder";
+import {EpRequirements} from "../../../sdk/ep-requirements";
+
+export class LineConfig extends WidgetConfig {
+
+    static readonly TITLE_KEY: string = "title";
+    static readonly NUMBER_MAPPING_KEY: string = "number-mapping";
+    static readonly TIMESTAMP_MAPPING_KEY: string = "timestamp-mapping";
+    static readonly MIN_Y_AXIS_KEY: string = "min-y-axis-key";
+    static readonly MAX_Y_AXIS_KEY: string = "max-y-axis-key";
+
+    getConfig(): DashboardWidgetSettings {
+        return WidgetConfigBuilder.create("line", "line")
+            .requiredSchema(SchemaRequirementsBuilder
+                .create()
+                .requiredPropertyWithUnaryMapping(LineConfig.TIMESTAMP_MAPPING_KEY, "Timestamp field", "", EpRequirements.timestampReq())
+                .requiredPropertyWithUnaryMapping(LineConfig.NUMBER_MAPPING_KEY, "Number field", "", EpRequirements.numberReq())
+                .build())
+            .requiredTextParameter(LineConfig.TITLE_KEY, "hi", "hi")
+            .requiredIntegerParameter(LineConfig.MIN_Y_AXIS_KEY, "Y-axis range (min)", "")
+            .requiredIntegerParameter(LineConfig.MAX_Y_AXIS_KEY, "Y-axis range (min)", "")
+            .build();
+    }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.css b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.css
new file mode 100644
index 0000000..65c8a0f
--- /dev/null
+++ b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.css
@@ -0,0 +1,11 @@
+.main-panel {
+    width:100%;
+    height: 100%;
+    display:inline-grid;
+    align-content: center;
+}
+
+::ng-deep .ngx-charts {
+    margin-left: 15px;
+    margin-top: -10px;
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.html b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.html
new file mode 100644
index 0000000..610c2ac
--- /dev/null
+++ b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.html
@@ -0,0 +1,23 @@
+<div fxFlex="100" fxLayoutAlign="center center" fxLayout="column" class="main-panel" #pbgChartContainer>
+    <ngx-charts-line-chart *ngIf="displayChart" #chart
+                           [showXAxisLabel]="false"
+                           [showYAxisLabel]="false"
+                           [timeline]="true"
+                           [view]="view"
+                           [autoScale]="true"
+                           [xAxis]="true"
+                           [yAxis]="true"
+                           [tooltipDisabled]="true"
+                           [animations]="false"
+                           [xAxisTickFormatting]="timestampTickFormatting"
+                           [results]="multi" style="margin-top:10px;margin-bottom:10px;">
+    </ngx-charts-line-chart>
+</div>
+<!--<ngx-charts-number-card *ngIf="displayChart" #chart-->
+<!--                        [results]="[{'name' : 'test', 'value': 'ads'}]"-->
+<!--                        [scheme]="'cool'"-->
+<!--                        [cardColor]="'blue'"-->
+<!--                        [bandColor]="'rgb(27, 20, 100)'"-->
+<!--                        [view]="view">-->
+<!--</ngx-charts-number-card>-->
+
diff --git a/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.ts b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.ts
new file mode 100644
index 0000000..a0827b1
--- /dev/null
+++ b/ui/src/app/dashboard-v2/components/widgets/line/line-widget.component.ts
@@ -0,0 +1,90 @@
+import {AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild} from "@angular/core";
+import {BaseStreamPipesWidget} from "../base/base-widget";
+import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-extractor";
+import {RxStompService} from "@stomp/ng2-stompjs";
+import {LineConfig} from "./line-config";
+import {ResizeService} from "../../../services/resize.service";
+import {GridsterInfo} from "../../../models/gridster-info.model";
+import {NumberCardComponent} from "@swimlane/ngx-charts";
+
+@Component({
+    selector: 'line-widget',
+    templateUrl: './line-widget.component.html',
+    styleUrls: ['./line-widget.component.css']
+})
+export class LineWidgetComponent extends BaseStreamPipesWidget implements OnInit, OnDestroy {
+
+    @ViewChild('pbgChartContainer') pbgChartContainer: ElementRef;
+    @ViewChild('chart') chart: NumberCardComponent;
+
+    multi:any = [];
+    view: any[] = [];
+
+    selectedNumberProperty: string;
+    selectedTimestampProperty: string;
+    title: string;
+    minYAxisRange: number;
+    maxYAxisRange: number;
+    displayChart: boolean = false;
+
+    constructor(rxStompService: RxStompService, private resizeService: ResizeService) {
+        super(rxStompService);
+    }
+
+    ngOnInit(): void {
+        super.ngOnInit();
+        this.view = [this.gridsterItem.width, this.gridsterItem.height];
+        this.displayChart = true;
+        this.resizeService.resizeSubject.subscribe(info => {
+            this.onResize(info);
+        });
+        this.multi = [
+            {
+                "name": this.selectedNumberProperty,
+                "series": [
+                ]
+            }];
+    }
+
+    ngOnDestroy(): void {
+        super.ngOnDestroy();
+    }
+
+    protected extractConfig(extractor: StaticPropertyExtractor) {
+        this.title = extractor.singleValueParameter(LineConfig.TITLE_KEY);
+        this.selectedNumberProperty = extractor.mappingPropertyValue(LineConfig.NUMBER_MAPPING_KEY);
+        this.selectedTimestampProperty = extractor.mappingPropertyValue(LineConfig.TIMESTAMP_MAPPING_KEY);
+        this.minYAxisRange = extractor.integerParameter(LineConfig.MIN_Y_AXIS_KEY);
+        this.maxYAxisRange = extractor.integerParameter(LineConfig.MAX_Y_AXIS_KEY);
+    }
+
+    protected onEvent(event: any) {
+        let time = event[this.selectedTimestampProperty];
+        let value = event[this.selectedNumberProperty];
+        this.makeEvent(time, value);
+    }
+
+    makeEvent(time: any, value: any): void {
+        this.multi[0].series.push({"name": time, "value": value});
+        if (this.multi[0].series.length > 10) {
+            this.multi[0].series.shift();
+        }
+        this.multi = [...this.multi];
+    }
+
+    timestampTickFormatting(timestamp: any): string {
+        var date = new Date(timestamp);
+        let timeString = date.getHours() + ':' + date.getMinutes().toString().substr(-2) + ':' + date.getSeconds().toString().substr(-2);
+        return timeString;
+    }
+
+    onResize(info: GridsterInfo) {
+        if (info.gridsterItem.id === this.gridsterItem.id) {
+            setTimeout(() => {
+                this.displayChart = false;
+                this.view = [info.gridsterItemComponent.width, info.gridsterItemComponent.height];
+                this.displayChart = true;
+            }, 100);
+        }
+    }
+}
\ No newline at end of file
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.ts
similarity index 100%
rename from ui/src/app/dashboard-v2/components/widgets/number/number-config.component.ts
rename to ui/src/app/dashboard-v2/components/widgets/number/number-config.ts
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-widget.component.css
similarity index 100%
rename from ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.css
rename to ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.css
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.html
similarity index 97%
rename from ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html
rename to ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.html
index 23ed019..314de1e 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.html
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.html
@@ -6,4 +6,4 @@
         <div *ngIf="isNumber(item)">{{item}}</div>
         <div *ngIf="!isNumber(item)">{{item}}</div>
     </div>
-</div>
\ No newline at end of file
+</div>
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-widget.component.ts
similarity index 78%
rename from ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts
rename to ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts
index 36f08a0..28c27f3 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-viz.component.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.ts
@@ -2,14 +2,14 @@ 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";
-import {NumberConfig} from "./number-config.component";
+import {NumberConfig} from "./number-config";
 
 @Component({
-    selector: 'number-viz',
-    templateUrl: './number-viz.component.html',
-    styleUrls: ['./number-viz.component.css']
+    selector: 'number-widget',
+    templateUrl: './number-widget.component.html',
+    styleUrls: ['./number-widget.component.css']
 })
-export class NumberVizComponent extends BaseStreamPipesWidget implements OnInit, OnDestroy {
+export class NumberWidgetComponent extends BaseStreamPipesWidget implements OnInit, OnDestroy {
 
     item: any;
     title: string;
diff --git a/ui/src/app/dashboard-v2/dashboard.module.ts b/ui/src/app/dashboard-v2/dashboard.module.ts
index 96ef342..5dc6c48 100644
--- a/ui/src/app/dashboard-v2/dashboard.module.ts
+++ b/ui/src/app/dashboard-v2/dashboard.module.ts
@@ -16,12 +16,15 @@ import {MatGridListModule} from "@angular/material/grid-list";
 import {ElementIconText} from "../services/get-element-icon-text.service";
 import {DashboardService} from "./services/dashboard.service";
 import {ConnectModule} from "../connect/connect.module";
-import {NumberVizComponent} from "./components/widgets/number/number-viz.component";
+import {NumberWidgetComponent} from "./components/widgets/number/number-widget.component";
 import {streamPipesStompConfig} from "./services/websocket.config";
 import {InjectableRxStompConfig, RxStompService, rxStompServiceFactory} from "@stomp/ng2-stompjs";
 import {DashboardOverviewComponent} from "./components/overview/dashboard-overview.component";
 import {EditDashboardDialogComponent} from "./dialogs/edit-dashboard/edit-dashboard-dialog.component";
 import {DashboardGridComponent} from "./components/grid/dashboard-grid.component";
+import {LineWidgetComponent} from "./components/widgets/line/line-widget.component";
+import {NgxChartsModule} from "@swimlane/ngx-charts";
+import {ResizeService} from "./services/resize.service";
 
 const dashboardWidgets = [
 
@@ -43,6 +46,7 @@ const dashboardWidgets = [
         ColorPickerModule,
         MatGridListModule,
         ConnectModule,
+        NgxChartsModule
     ],
     declarations: [
         DashboardComponent,
@@ -52,10 +56,12 @@ const dashboardWidgets = [
         DashboardWidgetComponent,
         AddVisualizationDialogComponent,
         EditDashboardDialogComponent,
-        NumberVizComponent
+        LineWidgetComponent,
+        NumberWidgetComponent
     ],
     providers: [
         DashboardService,
+        ResizeService,
         {
             provide: 'RestApi',
             useFactory: ($injector: any) => $injector.get('RestApi'),
diff --git a/ui/src/app/dashboard-v2/models/gridster-info.model.ts b/ui/src/app/dashboard-v2/models/gridster-info.model.ts
new file mode 100644
index 0000000..243c6a8
--- /dev/null
+++ b/ui/src/app/dashboard-v2/models/gridster-info.model.ts
@@ -0,0 +1,6 @@
+import {GridsterItem, GridsterItemComponent} from "angular-gridster2";
+
+export interface GridsterInfo {
+    gridsterItem: GridsterItem;
+    gridsterItemComponent: GridsterItemComponent
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/models/multi-series.model.ts b/ui/src/app/dashboard-v2/models/multi-series.model.ts
new file mode 100644
index 0000000..a01b0a9
--- /dev/null
+++ b/ui/src/app/dashboard-v2/models/multi-series.model.ts
@@ -0,0 +1,11 @@
+import {DashboardItem} from "./dashboard.model";
+
+export interface MultiSeries {
+    name?: string;
+    series?: Array<MultiSeriesEntry>;
+}
+
+export interface MultiSeriesEntry {
+    name: string;
+    value: any;
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/registry/widget-config-builder.ts b/ui/src/app/dashboard-v2/registry/widget-config-builder.ts
index 1e7df2c..18f5583 100644
--- a/ui/src/app/dashboard-v2/registry/widget-config-builder.ts
+++ b/ui/src/app/dashboard-v2/registry/widget-config-builder.ts
@@ -2,6 +2,8 @@ import {FreeTextStaticProperty} from "../../connect/model/FreeTextStaticProperty
 import {CollectedSchemaRequirements} from "../sdk/collected-schema-requirements";
 import {EventSchema} from "../../connect/schema-editor/model/EventSchema";
 import {DashboardWidgetSettings} from "../../core-model/dashboard/DashboardWidgetSettings";
+import {Vocabulary} from "../sdk/model/vocabulary";
+import {Datatypes} from "../sdk/model/datatypes";
 
 export class WidgetConfigBuilder {
 
@@ -19,10 +21,19 @@ export class WidgetConfigBuilder {
     }
 
     requiredTextParameter(id: string, label: string, description: string): WidgetConfigBuilder {
-        let fst: FreeTextStaticProperty = new FreeTextStaticProperty();
-        fst.internalName = id;
-        fst.label = label;
-        fst.description = description;
+        let fst: FreeTextStaticProperty = this.prepareStaticProperty(id, label, description, Datatypes.String.toUri())
+        this.widget.config.push(fst);
+        return this;
+    }
+
+    requiredIntegerParameter(id: string, label: string, description: string): WidgetConfigBuilder {
+        let fst: FreeTextStaticProperty = this.prepareStaticProperty(id, label, description, Datatypes.Integer.toUri())
+        this.widget.config.push(fst);
+        return this;
+    }
+
+    requiredFloatParameter(id: string, label: string, description: string): WidgetConfigBuilder {
+        let fst: FreeTextStaticProperty = this.prepareStaticProperty(id, label, description, Datatypes.Float.toUri())
         this.widget.config.push(fst);
         return this;
     }
@@ -34,6 +45,16 @@ export class WidgetConfigBuilder {
         return this;
     }
 
+    prepareStaticProperty(id: string, label: string, description: string, datatype: string) {
+        let fst: FreeTextStaticProperty = new FreeTextStaticProperty();
+        fst.internalName = id;
+        fst.label = label;
+        fst.description = description;
+        fst.requiredDatatype = datatype;
+
+        return fst;
+    }
+
     build(): DashboardWidgetSettings {
         return this.widget;
     }
diff --git a/ui/src/app/dashboard-v2/registry/widget-registry.ts b/ui/src/app/dashboard-v2/registry/widget-registry.ts
index be6355e..f71e3c6 100644
--- a/ui/src/app/dashboard-v2/registry/widget-registry.ts
+++ b/ui/src/app/dashboard-v2/registry/widget-registry.ts
@@ -1,10 +1,14 @@
-import {NumberConfig} from "../components/widgets/number/number-config.component";
+import {NumberConfig} from "../components/widgets/number/number-config";
 import {DashboardWidgetSettings} from "../../core-model/dashboard/DashboardWidgetSettings";
 import {WidgetConfig} from "../components/widgets/base/base-config";
+import {LineConfig} from "../components/widgets/line/line-config";
 
 export class WidgetRegistry {
 
-    private static availableWidgets: Array<WidgetConfig> = [new NumberConfig()];
+    private static availableWidgets: Array<WidgetConfig> = [
+        new NumberConfig(),
+        new LineConfig()
+    ];
 
     static getAvailableWidgetTemplates(): Array<DashboardWidgetSettings> {
         let widgetTemplates = new Array<DashboardWidgetSettings>();
diff --git a/ui/src/app/dashboard-v2/sdk/ep-requirements.ts b/ui/src/app/dashboard-v2/sdk/ep-requirements.ts
index c99f638..af5a743 100644
--- a/ui/src/app/dashboard-v2/sdk/ep-requirements.ts
+++ b/ui/src/app/dashboard-v2/sdk/ep-requirements.ts
@@ -9,6 +9,10 @@ export class EpRequirements {
         return ep;
     }
 
+    static timestampReq(): EventProperty {
+        return EpRequirements.domainPropertyReq("http://schema.org/DateTime");
+    }
+
     static numberReq(): EventProperty {
         return EpRequirements.datatypeReq(Datatypes.Number);
     }
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 37d68a4..f752fbc 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
@@ -20,6 +20,14 @@ export class StaticPropertyExtractor {
         return sp.value;
     }
 
+    stringParameter(internalId: string): string {
+        return this.singleValueParameter(internalId) as string;
+    }
+
+    integerParameter(internalId: string): number {
+        return this.singleValueParameter(internalId) as number;
+    }
+
     getStaticPropertyByName(internalId: string): StaticProperty {
         return this.staticProperties.find(sp => (sp.internalName == internalId));
     }
diff --git a/ui/src/app/dashboard-v2/services/resize.service.ts b/ui/src/app/dashboard-v2/services/resize.service.ts
new file mode 100644
index 0000000..e963231
--- /dev/null
+++ b/ui/src/app/dashboard-v2/services/resize.service.ts
@@ -0,0 +1,13 @@
+import {BehaviorSubject} from "rxjs";
+import {Injectable} from "@angular/core";
+import {GridsterInfo} from "../models/gridster-info.model";
+
+@Injectable()
+export class ResizeService {
+
+    public resizeSubject: BehaviorSubject<GridsterInfo> = new BehaviorSubject<GridsterInfo>(null);
+
+    public notify(info: GridsterInfo): void {
+        this.resizeSubject.next(info);
+    }
+}
\ No newline at end of file


[incubator-streampipes] 02/06: Improve editing of dashboards, display name and description

Posted by ri...@apache.org.
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

commit 0f44deea84bd3fdf3a275f969dff46e3aade3e53
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sun Feb 9 18:00:53 2020 +0100

    Improve editing of dashboards, display name and description
---
 .../model/dashboard/DashboardModel.java            |  9 ++++++
 ui/package.json                                    |  2 +-
 .../components/grid/dashboard-grid.component.html  |  4 +++
 .../overview/dashboard-overview.component.html     | 28 +++++++++++++++--
 .../overview/dashboard-overview.component.ts       | 11 ++++++-
 .../panel/dashboard-panel.component.html           |  6 ++--
 .../components/panel/dashboard-panel.component.ts  | 36 ++++++++++++++--------
 ui/src/app/dashboard-v2/dashboard.component.css    |  3 ++
 ui/src/app/dashboard-v2/dashboard.component.html   | 26 +++++++++++-----
 ui/src/app/dashboard-v2/dashboard.component.ts     | 11 +++++++
 .../edit-dashboard-dialog.component.html           |  1 +
 ui/src/app/dashboard-v2/models/dashboard.model.ts  |  1 +
 12 files changed, 111 insertions(+), 27 deletions(-)

diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardModel.java b/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardModel.java
index 7fcba5c..882ddf5 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardModel.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardModel.java
@@ -38,6 +38,7 @@ public class DashboardModel {
   private String id;
   private String name;
   private String description;
+  private boolean displayHeader;
 
   private List<DashboardItem> widgets;
 
@@ -92,4 +93,12 @@ public class DashboardModel {
   public void setWidgets(List<DashboardItem> widgets) {
     this.widgets = widgets;
   }
+
+  public boolean isDisplayHeader() {
+    return displayHeader;
+  }
+
+  public void setDisplayHeader(boolean displayHeader) {
+    this.displayHeader = displayHeader;
+  }
 }
diff --git a/ui/package.json b/ui/package.json
index 324941e..d53dc74 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -29,7 +29,7 @@
     "@angular/upgrade": "7.2.9",
     "@ngui/datetime-picker": "0.16.2",
     "@stomp/ng2-stompjs": "^7.2.0",
-    "@swimlane/ngx-charts": "10.1.0",
+    "@swimlane/ngx-charts": "13.0.2",
     "@uirouter/angular-hybrid": "7.0.0",
     "angular": "1.7.7",
     "angular-animate": "1.7.7",
diff --git a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
index 7a90a41..dc85ab7 100644
--- a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
+++ b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
@@ -1,3 +1,7 @@
+<div *ngIf="dashboard.displayHeader" class="text-center">
+    <h2>{{dashboard.name}}</h2>
+    <h3>{{dashboard.description}}</h3>
+</div>
 <gridster [options]="options" [ngClass]="editMode ? 'edit' : ''">
     <ng-container *ngFor="let item of dashboard.widgets">
         <gridster-item [item]="item">
diff --git a/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html b/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html
index b254d0a..35a2f3a 100644
--- a/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html
+++ b/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.html
@@ -33,13 +33,37 @@
             <table fxFlex="95" mat-table [dataSource]="dataSource" multiTemplateDataRows>
 
                 <ng-container matColumnDef="name">
-                    <th fxFlex="80" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Dashboard</th>
-                    <td fxFlex="80" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
+                    <th fxFlex="60" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Dashboard</th>
+                    <td fxFlex="60" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
                         {{element.name}}<br/>
                         {{element.description}}
                     </td>
                 </ng-container>
 
+                <ng-container matColumnDef="open">
+                    <th fxFlex="10" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Show</th>
+                    <td fxFlex="10" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
+                        <div fxLayout="row">
+                            <button mat-button mat-icon-button color="primary"
+                                    (click)="showDashboard(element)">
+                                <i class="material-icons">visibility</i>
+                            </button>
+                        </div>
+                    </td>
+                </ng-container>
+
+                <ng-container matColumnDef="openWindow">
+                    <th fxFlex="10" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Window</th>
+                    <td fxFlex="10" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
+                        <div fxLayout="row">
+                            <button mat-button mat-icon-button color="primary"
+                                    (click)="openExternalDashboard(element)">
+                                <i class="material-icons">open_in_new</i>
+                            </button>
+                        </div>
+                    </td>
+                </ng-container>
+
                 <ng-container matColumnDef="edit">
                     <th fxFlex="10" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Edit</th>
                     <td fxFlex="10" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
diff --git a/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.ts b/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.ts
index f492f9d..031a729 100644
--- a/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.ts
+++ b/ui/src/app/dashboard-v2/components/overview/dashboard-overview.component.ts
@@ -15,9 +15,10 @@ export class DashboardOverviewComponent implements OnInit {
 
     @Input() dashboards: Array<Dashboard>;
     @Output() reloadDashboardsEmitter = new EventEmitter<boolean>();
+    @Output() selectDashboardEmitter = new EventEmitter<Dashboard>();
 
     dataSource = new MatTableDataSource<Dashboard>();
-    displayedColumns: string[] = ['name', 'edit', 'delete'];
+    displayedColumns: string[] = ['name', 'open', 'openWindow', 'edit', 'delete'];
 
     constructor(private dashboardService: DashboardService,
                 public dialog: MatDialog) {
@@ -59,4 +60,12 @@ export class DashboardOverviewComponent implements OnInit {
         });
     }
 
+    showDashboard(dashboard: Dashboard) {
+        this.selectDashboardEmitter.emit(dashboard);
+    }
+
+    openExternalDashboard(dashboard: Dashboard) {
+
+    }
+
 }
\ 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 3b32940..55448cd 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,7 +1,7 @@
 <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)="toggleEditMode()"
-                style="margin-right:10px;">{{editMode ? 'Save' : 'Edit'}}
+    <div fxLayout="row wrap" style="margin-bottom:20px;" *ngIf="editMode">
+        <button mat-button mat-raised-button color="primary" (click)="updateDashboardAndCloseEditMode()"
+                style="margin-right:10px;">Save
         </button>
         <button mat-button mat-raised-button color="primary" (click)="addWidget()" [disabled]="!editMode">Add
             visualization</button>
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 e88c674..96d3216 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,4 +1,4 @@
-import {Component, Input, OnChanges, OnInit, SimpleChanges} from "@angular/core";
+import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from "@angular/core";
 import {Dashboard, DashboardConfig, DashboardItem} from "../../models/dashboard.model";
 import {Subscription} from "rxjs";
 import {GridType} from "angular-gridster2";
@@ -12,17 +12,17 @@ import {DashboardService} from "../../services/dashboard.service";
     templateUrl: './dashboard-panel.component.html',
     styleUrls: ['./dashboard-panel.component.css']
 })
-export class DashboardPanelComponent implements OnInit {
+export class DashboardPanelComponent implements OnInit, OnChanges {
 
     @Input() dashboard: Dashboard;
+    @Input("editMode") editMode: boolean;
+    @Output("editModeChange") editModeChange: EventEmitter<boolean> = new EventEmitter();
 
     public options: DashboardConfig;
     public items: DashboardItem[];
 
     protected subscription: Subscription;
 
-    editMode: boolean = false;
-
     constructor(private dashboardService: DashboardService,
                 public dialog: MatDialog) {}
 
@@ -30,10 +30,12 @@ export class DashboardPanelComponent implements OnInit {
         this.options = {
             disablePushOnDrag: true,
             draggable: { enabled: this.editMode },
-            gridType: GridType.ScrollVertical,
+            gridType: GridType.VerticalFixed,
             minCols: 8,
             maxCols: 8,
             minRows: 4,
+            fixedRowHeight: 100,
+            fixedColWidth: 100,
             resizable: { enabled: this.editMode }
         };
     }
@@ -72,14 +74,22 @@ export class DashboardPanelComponent implements OnInit {
         })
     }
 
-    toggleEditMode() {
-        if (this.editMode) {
-            this.updateDashboard();
+    updateDashboardAndCloseEditMode() {
+        this.updateDashboard();
+        this.editModeChange.emit(!(this.editMode));
+    }
+
+    ngOnChanges(changes: SimpleChanges): void {
+        if (changes["editMode"] && this.options) {
+            // if (this.editMode) {
+            //     this.updateDashboard();
+            // }
+            // 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();
         }
-        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/dashboard.component.css b/ui/src/app/dashboard-v2/dashboard.component.css
index e69de29..1dab0cc 100644
--- a/ui/src/app/dashboard-v2/dashboard.component.css
+++ b/ui/src/app/dashboard-v2/dashboard.component.css
@@ -0,0 +1,3 @@
+.mr-20 {
+    margin-right:20px;
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/dashboard.component.html b/ui/src/app/dashboard-v2/dashboard.component.html
index 9184530..a5f1b88 100644
--- a/ui/src/app/dashboard-v2/dashboard.component.html
+++ b/ui/src/app/dashboard-v2/dashboard.component.html
@@ -1,19 +1,31 @@
 <div fxLayout="column" class="page-container">
     <div fxLayout="row" style="padding:0px;background-color:#f6f6f6;">
-        <div fxLayout="fill" style="line-height:24px;border-bottom:1px solid #ccc">
-            <mat-tab-group [selectedIndex]="selectedIndex" (selectedIndexChange)="selectDashboard($event)">
-                <mat-tab label="Start"></mat-tab>
-                <mat-tab *ngFor="let dashboard of dashboards" label="{{dashboard.name}}"></mat-tab>
-            </mat-tab-group>
+        <div fxFlex="100" style="line-height:24px;border-bottom:1px solid #ccc">
+            <div fxFlex="100" fxLayout="row">
+                <div fxFlex fxLayoutAlign="start center">
+                    <mat-tab-group [selectedIndex]="selectedIndex" (selectedIndexChange)="selectDashboard($event)">
+                        <mat-tab label="Start"></mat-tab>
+                        <mat-tab *ngFor="let dashboard of dashboards" label="{{dashboard.name}}"></mat-tab>
+                    </mat-tab-group>
+                </div>
+                <div fxFlex fxLayoutAlign="end center" class="mr-20">
+                <button mat-button mat-icon-button color="primary"
+                        *ngIf="selectedIndex > 0" (click)="toggleEditMode()">
+                    <i class="material-icons">edit</i>
+                </button>
+                </div>
+            </div>
         </div>
     </div>
 
     <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100" *ngIf="dashboardsLoaded">
-    <dashboard-overview (reloadDashboardsEmitter)="getDashboards($event)" [dashboards]="dashboards"
+    <dashboard-overview (selectDashboardEmitter)="openDashboard($event)"
+                        (reloadDashboardsEmitter)="getDashboards($event)"
+                        [dashboards]="dashboards"
                         *ngIf="!dashboardTabSelected">
 
     </dashboard-overview>
-    <dashboard-panel fxLayout="column" [dashboard]="selectedDashboard"
+    <dashboard-panel fxLayout="column" [(editMode)]="editMode" [dashboard]="selectedDashboard"
                      style="height:100%;" *ngIf="dashboardTabSelected">
 
     </dashboard-panel>
diff --git a/ui/src/app/dashboard-v2/dashboard.component.ts b/ui/src/app/dashboard-v2/dashboard.component.ts
index 3d9d6c6..585efbc 100644
--- a/ui/src/app/dashboard-v2/dashboard.component.ts
+++ b/ui/src/app/dashboard-v2/dashboard.component.ts
@@ -15,6 +15,8 @@ export class DashboardComponent implements OnInit {
     dashboardsLoaded: boolean = false;
     dashboardTabSelected: boolean = false;
 
+    editMode: boolean = false;
+
     dashboards: Array<Dashboard>;
 
     constructor(private dashboardService: DashboardService) {}
@@ -24,8 +26,13 @@ export class DashboardComponent implements OnInit {
 
     }
 
+    openDashboard(dashboard: Dashboard) {
+        let index = this.dashboards.indexOf(dashboard);
+        this.selectDashboard((index + 1));
+    }
 
     selectDashboard(index: number) {
+        this.selectedIndex = index;
         if (index == 0) {
             this.dashboardTabSelected = false;
         } else {
@@ -42,4 +49,8 @@ export class DashboardComponent implements OnInit {
             this.dashboardsLoaded = true;
         });
     }
+
+    toggleEditMode() {
+        this.editMode = ! (this.editMode);
+    }
 }
diff --git a/ui/src/app/dashboard-v2/dialogs/edit-dashboard/edit-dashboard-dialog.component.html b/ui/src/app/dashboard-v2/dialogs/edit-dashboard/edit-dashboard-dialog.component.html
index a1d273e..980b679 100644
--- a/ui/src/app/dashboard-v2/dialogs/edit-dashboard/edit-dashboard-dialog.component.html
+++ b/ui/src/app/dashboard-v2/dialogs/edit-dashboard/edit-dashboard-dialog.component.html
@@ -37,6 +37,7 @@
                 <mat-label>Description</mat-label>
                 <input matInput [(ngModel)]="dashboard.description">
             </mat-form-field>
+            <mat-checkbox [(ngModel)]="dashboard.displayHeader">Show name and description in dashboard</mat-checkbox>
 
         </div>
     </div>
diff --git a/ui/src/app/dashboard-v2/models/dashboard.model.ts b/ui/src/app/dashboard-v2/models/dashboard.model.ts
index 65aaa96..44b31a3 100644
--- a/ui/src/app/dashboard-v2/models/dashboard.model.ts
+++ b/ui/src/app/dashboard-v2/models/dashboard.model.ts
@@ -11,6 +11,7 @@ export interface Dashboard {
     id?: string;
     name?: string;
     description?: string;
+    displayHeader?: boolean;
     widgets?: Array<DashboardItem>;
     _id?: string;
     _rev?: string;


[incubator-streampipes] 06/06: STREAMPIPES-77: Add support for mapping properties in UI

Posted by ri...@apache.org.
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

commit 7077056c1106c5b1518a7d4c0753b9315ff45926
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Wed Feb 12 09:42:55 2020 +0100

    STREAMPIPES-77: Add support for mapping properties in UI
---
 ui/src/app/connect/model/MappingPropertyNary.ts    |  4 +-
 .../static-mapping-nary.component.html             | 16 ++-----
 .../static-mapping-nary.component.ts               | 48 +++++++++++++------
 .../static-mapping-unary.component.ts              | 32 ++++++-------
 .../static-mapping/static-mapping.ts               | 20 ++++++++
 .../static-property-util.service.ts                |  3 +-
 .../static-property.component.html                 |  2 +-
 .../widget/dashboard-widget.component.html         |  4 ++
 .../components/widgets/base/base-widget.ts         |  2 -
 .../widgets/number/number-widget.component.css     |  3 +-
 .../components/widgets/table/table-config.ts       | 26 +++++++++++
 .../widgets/table/table-widget.component.html      | 11 +++++
 .../widgets/table/table-widget.component.ts        | 54 ++++++++++++++++++++++
 ui/src/app/dashboard-v2/dashboard.module.ts        |  8 +++-
 .../add-visualization-dialog.component.ts          |  3 +-
 .../app/dashboard-v2/registry/widget-registry.ts   |  4 +-
 ui/src/app/dashboard-v2/sdk/ep-requirements.ts     |  4 ++
 .../sdk/extractor/static-property-extractor.ts     | 10 ++++
 .../sdk/schema-requirements-builder.ts             | 24 ++++++++--
 .../platform-services/tsonld-serializer.service.ts |  2 +
 20 files changed, 220 insertions(+), 60 deletions(-)

diff --git a/ui/src/app/connect/model/MappingPropertyNary.ts b/ui/src/app/connect/model/MappingPropertyNary.ts
index 361df1e..aff6133 100644
--- a/ui/src/app/connect/model/MappingPropertyNary.ts
+++ b/ui/src/app/connect/model/MappingPropertyNary.ts
@@ -36,10 +36,8 @@ export class MappingPropertyNary extends StaticProperty {
   @RdfProperty('sp:mapsTo')
   public selectedProperties: string[];
 
-
-  constructor(id: string) {
+  constructor() {
       super();
-      this.id = id;
   }
 
 }
diff --git a/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.html b/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.html
index 66bb2f6..647a2cf 100644
--- a/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.html
+++ b/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.html
@@ -23,16 +23,10 @@
         </p>
     </div>
     <div fxFlex fxLayout="row">
-        <form fxFlex [formGroup]="freeTextForm" style="padding-left: 10px;">
-            <mat-form-field fxFlex>
-                <input fxFlex id="{{ 'input-' + staticProperty.label.toLowerCase() }}" matInput [placeholder]="staticProperty.label" [(ngModel)]="staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value"
-                       formControlName="freeStaticText" (ngModelChange)="valueChange(staticPropertyUtil.asFreeTextStaticProperty(staticProperty).value)"
-                       required>
-
-                <mat-error *ngIf="!hasInput">
-                    {{errorMessage}}
-                </mat-error>
-            </mat-form-field>
-        </form>
+                <mat-checkbox *ngFor="let property of availableProperties"
+                              (change)="selectOption(property, $event)"
+                              style="margin-left: 10px;">
+                    {{getName(property)}}
+                </mat-checkbox>
     </div>
 </div>
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.ts b/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.ts
index f481bce..0469a62 100644
--- a/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.ts
+++ b/ui/src/app/connect/static-properties/static-mapping-nary/static-mapping-nary.component.ts
@@ -17,11 +17,13 @@
  */
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { FreeTextStaticProperty } from '../../model/FreeTextStaticProperty';
-import { StaticProperty } from '../../model/StaticProperty';
 import { FormControl, Validators, FormGroup } from '@angular/forms';
 import {StaticPropertyUtilService} from '../static-property-util.service';
 import {MappingPropertyNary} from "../../model/MappingPropertyNary";
+import {StaticMappingComponent} from "../static-mapping/static-mapping";
+import {PropertySelectorService} from "../../../services/property-selector.service";
+import {EventProperty} from "../../schema-editor/model/EventProperty";
+import {EventSchema} from "../../schema-editor/model/EventSchema";
 
 
 @Component({
@@ -29,28 +31,40 @@ import {MappingPropertyNary} from "../../model/MappingPropertyNary";
     templateUrl: './static-mapping-nary.component.html',
     styleUrls: ['./static-mapping-nary.component.css']
 })
-export class StaticMappingNaryComponent implements OnInit {
+export class StaticMappingNaryComponent extends StaticMappingComponent implements OnInit {
 
 
     @Input() staticProperty: MappingPropertyNary;
+    @Input() eventSchema: EventSchema;
     @Output() inputEmitter: EventEmitter<Boolean> = new EventEmitter<Boolean>();
-    
-    private freeTextForm: FormGroup;
+
     private inputValue: String;
     private hasInput: Boolean;
-    private errorMessage = "Please enter a value";
+    private availableProperties: Array<EventProperty>;
 
-    constructor(private staticPropertyUtil: StaticPropertyUtilService){
+    constructor(staticPropertyUtil: StaticPropertyUtilService,
+                PropertySelectorService: PropertySelectorService){
+        super(staticPropertyUtil, PropertySelectorService);
+    }
 
+    ngOnInit() {
+        this.availableProperties = this.extractPossibleSelections();
+        this.availableProperties.forEach(ep => ep.propertySelector = this.firstStreamPropertySelector + ep.runtimeName);
+        if (!this.staticProperty.selectedProperties) {
+            this.staticProperty.selectedProperties = [];
+        }
     }
 
+    selectOption(property: EventProperty, $event) {
+        if ($event.checked) {
+            this.staticProperty.selectedProperties.push(this.makeSelector(property));
+        } else {
+            this.staticProperty.selectedProperties.splice(this.staticProperty.selectedProperties.indexOf(this.makeSelector(property)));
+        }
+    }
 
-    ngOnInit() {
-        this.freeTextForm = new FormGroup({
-            'freeStaticText':new FormControl(this.inputValue, [
-                Validators.required,
-            ]),
-        })
+    makeSelector(property: EventProperty) {
+        return this.firstStreamPropertySelector + property.runtimeName;
     }
 
     valueChange(inputValue) {
@@ -65,4 +79,12 @@ export class StaticMappingNaryComponent implements OnInit {
         this.inputEmitter.emit(this.hasInput);
     }
 
+    extractPossibleSelections(): Array<EventProperty> {
+        return this.eventSchema.eventProperties.filter(ep => this.isInSelection(ep));
+    }
+
+    isInSelection(ep: EventProperty): boolean {
+        return this.staticProperty.mapsFromOptions.some(maps => maps === this.firstStreamPropertySelector + ep.runtimeName);
+    }
+
 }
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
index 19b73ae..6b10140 100644
--- a/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
+++ b/ui/src/app/connect/static-properties/static-mapping-unary/static-mapping-unary.component.ts
@@ -25,6 +25,7 @@ import {EventSchema} from '../../schema-editor/model/EventSchema';
 import {PropertySelectorService} from "../../../services/property-selector.service";
 import {MappingPropertyUnary} from "../../model/MappingPropertyUnary";
 import {EventProperty} from "../../schema-editor/model/EventProperty";
+import {StaticMappingComponent} from "../static-mapping/static-mapping";
 
 
 @Component({
@@ -32,27 +33,30 @@ import {EventProperty} from "../../schema-editor/model/EventProperty";
     templateUrl: './static-mapping-unary.component.html',
     styleUrls: ['./static-mapping-unary.component.css']
 })
-export class StaticMappingUnaryComponent implements OnInit {
-
+export class StaticMappingUnaryComponent extends StaticMappingComponent implements OnInit {
 
+    @Output() inputEmitter: EventEmitter<Boolean> = new EventEmitter<Boolean>();
     @Input() staticProperty: MappingPropertyUnary;
     @Input() eventSchema: EventSchema;
 
-    @Output() inputEmitter: EventEmitter<Boolean> = new EventEmitter<Boolean>();
-    
     private unaryTextForm: FormGroup;
     private inputValue: String;
     private hasInput: Boolean;
     private errorMessage = "Please enter a value";
     private availableProperties: Array<EventProperty>;
 
-    private firstStreamPropertySelector: string = "s0::";
-
-    constructor(private staticPropertyUtil: StaticPropertyUtilService,
-                private PropertySelectorService: PropertySelectorService){
+    constructor(staticPropertyUtil: StaticPropertyUtilService,
+                PropertySelectorService: PropertySelectorService){
+        super(staticPropertyUtil, PropertySelectorService);
+    }
 
+    extractPossibleSelections(): Array<EventProperty> {
+        return this.eventSchema.eventProperties.filter(ep => this.isInSelection(ep));
     }
 
+    isInSelection(ep: EventProperty): boolean {
+        return this.staticProperty.mapsFromOptions.some(maps => maps === this.firstStreamPropertySelector + ep.runtimeName);
+    }
 
     ngOnInit() {
         this.availableProperties = this.extractPossibleSelections();
@@ -64,13 +68,7 @@ export class StaticMappingUnaryComponent implements OnInit {
         })
     }
 
-    extractPossibleSelections(): Array<EventProperty> {
-        return this.eventSchema.eventProperties.filter(ep => this.isInSelection(ep));
-    }
 
-    isInSelection(ep: EventProperty): boolean {
-        return this.staticProperty.mapsFromOptions.some(maps => maps === this.firstStreamPropertySelector + ep.runtimeName);
-    }
 
     valueChange(inputValue) {
         this.inputValue = inputValue;
@@ -84,10 +82,6 @@ export class StaticMappingUnaryComponent implements OnInit {
         this.inputEmitter.emit(this.hasInput);
     }
 
-    getName(eventProperty) {
-    return eventProperty.label
-      ? eventProperty.label
-      : eventProperty.runTimeName;
-  }
+
 
 }
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts b/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
index e69de29..d531bc2 100644
--- a/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
+++ b/ui/src/app/connect/static-properties/static-mapping/static-mapping.ts
@@ -0,0 +1,20 @@
+import {StaticPropertyUtilService} from "../static-property-util.service";
+import {PropertySelectorService} from "../../../services/property-selector.service";
+
+
+export abstract class StaticMappingComponent {
+
+    protected firstStreamPropertySelector: string = "s0::";
+
+    constructor(private staticPropertyUtil: StaticPropertyUtilService,
+                private PropertySelectorService: PropertySelectorService){
+
+    }
+
+    getName(eventProperty) {
+        return eventProperty.label
+            ? eventProperty.label
+            : eventProperty.runTimeName;
+    }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/connect/static-properties/static-property-util.service.ts b/ui/src/app/connect/static-properties/static-property-util.service.ts
index 325e5d2..b832572 100644
--- a/ui/src/app/connect/static-properties/static-property-util.service.ts
+++ b/ui/src/app/connect/static-properties/static-property-util.service.ts
@@ -63,7 +63,8 @@ export class StaticPropertyUtilService{
             clone.selectedProperty = val.selectedProperty;
         }
         else if (val instanceof MappingPropertyNary) {
-            clone = new MappingPropertyNary(id);
+            clone = new MappingPropertyNary();
+            clone.id = id;
             clone.requirementSelector = val.requirementSelector;
             clone.mapsFromOptions = val.mapsFromOptions;
             clone.propertyScope = val.propertyScope;
diff --git a/ui/src/app/connect/static-properties/static-property.component.html b/ui/src/app/connect/static-properties/static-property.component.html
index 26493db..0092d2b 100644
--- a/ui/src/app/connect/static-properties/static-property.component.html
+++ b/ui/src/app/connect/static-properties/static-property.component.html
@@ -62,7 +62,7 @@
                          [eventSchema]="eventSchema" (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty">
 </app-static-mapping-unary>
 
-<app-static-mapping-nary *ngIf="isMappingNaryProperty(staticProperty)"
+<app-static-mapping-nary *ngIf="isMappingNaryProperty(staticProperty)" [eventSchema]="eventSchema"
                          (inputEmitter)="valueChange($event)" [staticProperty]="staticProperty">
 </app-static-mapping-nary>
 
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 f1fb0f9..c6b258e 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
@@ -20,6 +20,10 @@
                 <div *ngIf="widget.widgetType === 'line'" class="h-100 p-0">
                     <line-widget [gridsterItem]="item" [widget]="widget" [widgetConfig]="configuredWidget"></line-widget>
                 </div>
+                <div *ngIf="widget.widgetType === 'table'" class="h-100 p-0">
+                    <table-widget [gridsterItem]="item" [widget]="widget"
+                                  [widgetConfig]="configuredWidget"></table-widget>
+                </div>
             </div>
         </div>
     </div>
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 0dc219a..4301c0c 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
@@ -1,5 +1,3 @@
-import {EventSchema} from "../../../../connect/schema-editor/model/EventSchema";
-import {StaticProperty} from "../../../../connect/model/StaticProperty";
 import {Input, OnInit} from "@angular/core";
 import {DashboardItem} from "../../../models/dashboard.model";
 import {DashboardWidget} from "../../../../core-model/dashboard/DashboardWidget";
diff --git a/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.css b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.css
index 154fb78..f8cf1c7 100644
--- a/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.css
+++ b/ui/src/app/dashboard-v2/components/widgets/number/number-widget.component.css
@@ -13,5 +13,6 @@
 }
 
 .numberItem {
-    font-size:30px;
+    font-size:60px;
+    font-weight:bold;
 }
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/table/table-config.ts b/ui/src/app/dashboard-v2/components/widgets/table/table-config.ts
index e69de29..292ce50 100644
--- a/ui/src/app/dashboard-v2/components/widgets/table/table-config.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/table/table-config.ts
@@ -0,0 +1,26 @@
+import {WidgetConfig} from "../base/base-config";
+import {DashboardWidgetSettings} from "../../../../core-model/dashboard/DashboardWidgetSettings";
+import {WidgetConfigBuilder} from "../../../registry/widget-config-builder";
+import {SchemaRequirementsBuilder} from "../../../sdk/schema-requirements-builder";
+import {EpRequirements} from "../../../sdk/ep-requirements";
+
+export class TableConfig extends WidgetConfig {
+
+    static readonly TITLE_KEY: string = "title-key";
+    static readonly SELECTED_PROPERTIES_KEYS: string = "selected-fields-key";
+
+    constructor() {
+        super();
+    }
+
+    getConfig(): DashboardWidgetSettings {
+        return WidgetConfigBuilder.create("table", "table")
+            .requiredSchema(SchemaRequirementsBuilder
+                .create()
+                .requiredPropertyWithNaryMapping(TableConfig.SELECTED_PROPERTIES_KEYS, "Select properties", "", EpRequirements.anyProperty())
+                .build())
+            .requiredTextParameter(TableConfig.TITLE_KEY, "Title", "The title")
+            .build();
+    }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.html b/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.html
index e69de29..92f9ff0 100644
--- a/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.html
+++ b/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.html
@@ -0,0 +1,11 @@
+<table mat-table [dataSource]="dataSource" style="width:100%;">
+
+    <ng-container *ngFor="let element of selectedProperties" [cdkColumnDef]="element">
+        <th mat-header-cell *matHeaderCellDef><label>{{element}}</label></th>
+        <td mat-cell *matCellDef="let row">{{row[element]}}</td>
+    </ng-container>
+
+    <tr mat-header-row *matHeaderRowDef="selectedProperties; sticky: true"></tr>
+    <tr mat-row *matRowDef="let row; columns: selectedProperties;"></tr>
+
+</table>
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.ts b/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.ts
index e69de29..e4f392c 100644
--- a/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.ts
+++ b/ui/src/app/dashboard-v2/components/widgets/table/table-widget.component.ts
@@ -0,0 +1,54 @@
+import {Component, OnDestroy, OnInit} from "@angular/core";
+import {BaseStreamPipesWidget} from "../base/base-widget";
+import {RxStompService} from "@stomp/ng2-stompjs";
+import {StaticPropertyExtractor} from "../../../sdk/extractor/static-property-extractor";
+import {MatTableDataSource} from "@angular/material/table";
+import {TableConfig} from "./table-config";
+
+@Component({
+    selector: 'table-widget',
+    templateUrl: './table-widget.component.html',
+    styleUrls: ['./table-widget.component.css']
+})
+export class TableWidgetComponent extends BaseStreamPipesWidget implements OnInit, OnDestroy {
+
+    title: string;
+    selectedProperties: Array<string>;
+
+    displayedColumns: String[] = [];
+    dataSource = new MatTableDataSource();
+
+    constructor(rxStompService: RxStompService) {
+        super(rxStompService);
+    }
+
+    ngOnInit(): void {
+        super.ngOnInit();
+    }
+
+    ngOnDestroy(): void {
+        super.ngOnDestroy();
+    }
+
+    extractConfig(extractor: StaticPropertyExtractor) {
+        this.title = extractor.singleValueParameter(TableConfig.TITLE_KEY);
+        this.selectedProperties = extractor.mappingPropertyValues(TableConfig.SELECTED_PROPERTIES_KEYS);
+    }
+
+    protected onEvent(event: any) {
+        this.dataSource.data.unshift(this.createTableObject(event));
+        if (this.dataSource.data.length > 10) {
+            this.dataSource.data.pop();
+        }
+        this.dataSource.data = [...this.dataSource.data];
+    }
+
+    createTableObject(event: any) {
+        let object = {};
+        this.selectedProperties.forEach((key, index) => {
+            object[key] = event[key];
+        });
+        return object;
+    }
+
+}
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/dashboard.module.ts b/ui/src/app/dashboard-v2/dashboard.module.ts
index 5dc6c48..43f1e1d 100644
--- a/ui/src/app/dashboard-v2/dashboard.module.ts
+++ b/ui/src/app/dashboard-v2/dashboard.module.ts
@@ -25,6 +25,8 @@ import {DashboardGridComponent} from "./components/grid/dashboard-grid.component
 import {LineWidgetComponent} from "./components/widgets/line/line-widget.component";
 import {NgxChartsModule} from "@swimlane/ngx-charts";
 import {ResizeService} from "./services/resize.service";
+import {TableWidgetComponent} from "./components/widgets/table/table-widget.component";
+import {CdkTableModule} from "@angular/cdk/table";
 
 const dashboardWidgets = [
 
@@ -46,7 +48,8 @@ const dashboardWidgets = [
         ColorPickerModule,
         MatGridListModule,
         ConnectModule,
-        NgxChartsModule
+        NgxChartsModule,
+        CdkTableModule,
     ],
     declarations: [
         DashboardComponent,
@@ -57,7 +60,8 @@ const dashboardWidgets = [
         AddVisualizationDialogComponent,
         EditDashboardDialogComponent,
         LineWidgetComponent,
-        NumberWidgetComponent
+        NumberWidgetComponent,
+        TableWidgetComponent
     ],
     providers: [
         DashboardService,
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 9c7b1c8..b55d71c 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
@@ -29,6 +29,7 @@ import {DashboardWidget} from "../../../core-model/dashboard/DashboardWidget";
 import {DashboardWidgetSettings} from "../../../core-model/dashboard/DashboardWidgetSettings";
 import {VisualizablePipeline} from "../../../core-model/dashboard/VisualizablePipeline";
 import {Dashboard} from "../../models/dashboard.model";
+import {MappingPropertyNary} from "../../../connect/model/MappingPropertyNary";
 
 @Component({
     selector: 'add-visualization-dialog-component',
@@ -110,7 +111,7 @@ export class AddVisualizationDialogComponent {
     selectWidget(widget) {
         this.selectedWidget = widget;
         this.selectedWidget.config.forEach(sp => {
-            if (sp instanceof MappingPropertyUnary) {
+            if (sp instanceof MappingPropertyUnary || sp instanceof MappingPropertyNary) {
                 let requirement: EventProperty = this.findRequirement(this.selectedWidget.requiredSchema, sp.internalName);
                 sp.mapsFromOptions = new MappingPropertyGenerator(requirement, this.selectedPipeline.schema.eventProperties).computeMatchingProperties();
             }
diff --git a/ui/src/app/dashboard-v2/registry/widget-registry.ts b/ui/src/app/dashboard-v2/registry/widget-registry.ts
index f71e3c6..bb687ac 100644
--- a/ui/src/app/dashboard-v2/registry/widget-registry.ts
+++ b/ui/src/app/dashboard-v2/registry/widget-registry.ts
@@ -2,12 +2,14 @@ import {NumberConfig} from "../components/widgets/number/number-config";
 import {DashboardWidgetSettings} from "../../core-model/dashboard/DashboardWidgetSettings";
 import {WidgetConfig} from "../components/widgets/base/base-config";
 import {LineConfig} from "../components/widgets/line/line-config";
+import {TableConfig} from "../components/widgets/table/table-config";
 
 export class WidgetRegistry {
 
     private static availableWidgets: Array<WidgetConfig> = [
         new NumberConfig(),
-        new LineConfig()
+        new LineConfig(),
+        new TableConfig()
     ];
 
     static getAvailableWidgetTemplates(): Array<DashboardWidgetSettings> {
diff --git a/ui/src/app/dashboard-v2/sdk/ep-requirements.ts b/ui/src/app/dashboard-v2/sdk/ep-requirements.ts
index af5a743..646f7c0 100644
--- a/ui/src/app/dashboard-v2/sdk/ep-requirements.ts
+++ b/ui/src/app/dashboard-v2/sdk/ep-requirements.ts
@@ -9,6 +9,10 @@ export class EpRequirements {
         return ep;
     }
 
+    static anyProperty(): EventProperty {
+        return EpRequirements.ep();
+    }
+
     static timestampReq(): EventProperty {
         return EpRequirements.domainPropertyReq("http://schema.org/DateTime");
     }
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 aa55a89..f17cb61 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
@@ -3,6 +3,7 @@ import {StaticProperty} from "../../../connect/model/StaticProperty";
 import {MappingPropertyUnary} from "../../../connect/model/MappingPropertyUnary";
 import {FreeTextStaticProperty} from "../../../connect/model/FreeTextStaticProperty";
 import {ColorPickerStaticProperty} from "../../../connect/model/ColorPickerStaticProperty";
+import {MappingPropertyNary} from "../../../connect/model/MappingPropertyNary";
 
 export class StaticPropertyExtractor {
 
@@ -16,6 +17,15 @@ export class StaticPropertyExtractor {
         return this.removePrefix(sp.selectedProperty);
     }
 
+    mappingPropertyValues(internalId: string): Array<string> {
+        let sp: MappingPropertyNary = this.getStaticPropertyByName(internalId) as MappingPropertyNary;
+        let properties: Array<string> = [];
+        sp.selectedProperties.forEach(ep => {
+           properties.push(this.removePrefix(ep));
+        });
+        return properties;
+    }
+
     singleValueParameter(internalId: string): any {
         let sp: FreeTextStaticProperty = this.getStaticPropertyByName(internalId) as FreeTextStaticProperty;
         return sp.value;
diff --git a/ui/src/app/dashboard-v2/sdk/schema-requirements-builder.ts b/ui/src/app/dashboard-v2/sdk/schema-requirements-builder.ts
index 736aa21..b2a40b3 100644
--- a/ui/src/app/dashboard-v2/sdk/schema-requirements-builder.ts
+++ b/ui/src/app/dashboard-v2/sdk/schema-requirements-builder.ts
@@ -2,6 +2,7 @@ import {EventProperty} from "../../connect/schema-editor/model/EventProperty";
 import {StaticProperty} from "../../connect/model/StaticProperty";
 import {CollectedSchemaRequirements} from "./collected-schema-requirements";
 import {MappingPropertyUnary} from "../../connect/model/MappingPropertyUnary";
+import {MappingPropertyNary} from "../../connect/model/MappingPropertyNary";
 
 export class SchemaRequirementsBuilder {
 
@@ -19,11 +20,7 @@ export class SchemaRequirementsBuilder {
 
     requiredPropertyWithUnaryMapping(internalId: string, label: string, description: string, eventProperty: EventProperty): SchemaRequirementsBuilder {
         eventProperty.setRuntimeName(internalId);
-        let mp = new MappingPropertyUnary();
-        mp.internalName = internalId;
-        mp.label = label;
-        mp.description = description;
-        mp.internalName = internalId;
+        let mp = this.makeMappingProperty(internalId, label, description, new MappingPropertyUnary());
 
         this.staticProperties.push(mp);
         this.requiredEventProperties.push(eventProperty);
@@ -31,6 +28,23 @@ export class SchemaRequirementsBuilder {
         return this;
     }
 
+    requiredPropertyWithNaryMapping(internalId: string, label: string, description: string, eventProperty: EventProperty): SchemaRequirementsBuilder {
+        eventProperty.setRuntimeName(internalId);
+        let mp = this.makeMappingProperty(internalId, label, description, new MappingPropertyNary());
+
+        this.staticProperties.push(mp);
+        this.requiredEventProperties.push(eventProperty);
+
+        return this;
+    }
+
+    makeMappingProperty(internalId: string, label: string, description: string, sp: StaticProperty): StaticProperty {
+        sp.internalName = internalId;
+        sp.label = label;
+        sp.description = description;
+        return sp;
+    }
+
     build() {
         return new CollectedSchemaRequirements(this.requiredEventProperties, this.staticProperties);
     }
diff --git a/ui/src/app/platform-services/tsonld-serializer.service.ts b/ui/src/app/platform-services/tsonld-serializer.service.ts
index ee66a5c..4cb1322 100644
--- a/ui/src/app/platform-services/tsonld-serializer.service.ts
+++ b/ui/src/app/platform-services/tsonld-serializer.service.ts
@@ -97,6 +97,7 @@ import {DashboardWidget} from "../core-model/dashboard/DashboardWidget";
 import {DashboardWidgetDataConfig} from "../core-model/dashboard/DashboardWidgetDataConfig";
 import {DashboardWidgetSettings} from "../core-model/dashboard/DashboardWidgetSettings";
 import {ColorPickerStaticProperty} from "../connect/model/ColorPickerStaticProperty";
+import {MappingPropertyNary} from "../connect/model/MappingPropertyNary";
 
 
 @Injectable()
@@ -126,6 +127,7 @@ export class TsonLdSerializerService {
         tsonld.addClassMapping(EventPropertyNested);
         tsonld.addClassMapping(PipelineTemplateInvocation);
         tsonld.addClassMapping(MappingPropertyUnary);
+        tsonld.addClassMapping(MappingPropertyNary);
         tsonld.addClassMapping(EventPropertyList);
         tsonld.addClassMapping(EventPropertyPrimitive);
         tsonld.addClassMapping(DomainPropertyProbability);


[incubator-streampipes] 01/06: STREAMPIPES-58: Persist dashboard layout changes

Posted by ri...@apache.org.
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

commit 202c5f4734d61e5af23b77ddf99a633bc87d7128
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sun Feb 9 16:25:52 2020 +0100

    STREAMPIPES-58: Persist dashboard layout changes
---
 .../components/grid/dashboard-grid.component.css       |  8 ++++++++
 .../components/grid/dashboard-grid.component.html      |  7 +++++++
 .../components/grid/dashboard-grid.component.ts        | 18 ++++++++++++++++++
 .../components/panel/dashboard-panel.component.css     |  8 ++------
 .../components/panel/dashboard-panel.component.html    |  9 +--------
 .../components/panel/dashboard-panel.component.ts      |  3 +++
 ui/src/app/dashboard-v2/dashboard.module.ts            |  2 ++
 ui/src/app/dashboard-v2/models/widget-data.model.ts    |  6 ------
 8 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.css b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.css
index e69de29..b326dde 100644
--- a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.css
+++ b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.css
@@ -0,0 +1,8 @@
+
+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/grid/dashboard-grid.component.html b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
index e69de29..7a90a41 100644
--- a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
+++ b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.html
@@ -0,0 +1,7 @@
+<gridster [options]="options" [ngClass]="editMode ? 'edit' : ''">
+    <ng-container *ngFor="let item of dashboard.widgets">
+        <gridster-item [item]="item">
+            <dashboard-widget [widget]="item" [editMode]="editMode"></dashboard-widget>
+        </gridster-item>
+    </ng-container>
+</gridster>
\ No newline at end of file
diff --git a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts
index e69de29..278f7dd 100644
--- a/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts
+++ b/ui/src/app/dashboard-v2/components/grid/dashboard-grid.component.ts
@@ -0,0 +1,18 @@
+import {Component, Input, OnInit} from "@angular/core";
+import {Dashboard, DashboardConfig} from "../../models/dashboard.model";
+
+@Component({
+    selector: 'dashboard-grid',
+    templateUrl: './dashboard-grid.component.html',
+    styleUrls: ['./dashboard-grid.component.css']
+})
+export class DashboardGridComponent implements OnInit {
+
+    @Input() editMode: boolean;
+    @Input() dashboard: Dashboard;
+    @Input() options: DashboardConfig;
+
+    ngOnInit(): void {
+    }
+
+}
\ No newline at end of file
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 bbc929d..476acda 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
@@ -2,10 +2,6 @@
     margin: 20px;
 }
 
-gridster ::ng-deep {
-    background: white;
+.h-100 {
+    height:100%;
 }
-
-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 fd1362a..3b32940 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
@@ -5,14 +5,7 @@
         </button>
         <button mat-button mat-raised-button color="primary" (click)="addWidget()" [disabled]="!editMode">Add
             visualization</button>
-
     </div>
 
-    <gridster [options]="options" [ngClass]="editMode ? 'edit' : ''">
-        <ng-container *ngFor="let item of dashboard.widgets">
-            <gridster-item [item]="item">
-                <dashboard-widget [widget]="item" [editMode]="editMode"></dashboard-widget>
-            </gridster-item>
-        </ng-container>
-    </gridster>
+    <dashboard-grid [editMode]="editMode" [dashboard]="dashboard" [options]="options" class="h-100"></dashboard-grid>
 </div>
\ No newline at end of file
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 3de4516..e88c674 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
@@ -73,6 +73,9 @@ export class DashboardPanelComponent implements OnInit {
     }
 
     toggleEditMode() {
+        if (this.editMode) {
+            this.updateDashboard();
+        }
         this.editMode = !(this.editMode);
         this.options.draggable.enabled = this.editMode;
         this.options.resizable.enabled = this.editMode;
diff --git a/ui/src/app/dashboard-v2/dashboard.module.ts b/ui/src/app/dashboard-v2/dashboard.module.ts
index e166d23..96ef342 100644
--- a/ui/src/app/dashboard-v2/dashboard.module.ts
+++ b/ui/src/app/dashboard-v2/dashboard.module.ts
@@ -21,6 +21,7 @@ import {streamPipesStompConfig} from "./services/websocket.config";
 import {InjectableRxStompConfig, RxStompService, rxStompServiceFactory} from "@stomp/ng2-stompjs";
 import {DashboardOverviewComponent} from "./components/overview/dashboard-overview.component";
 import {EditDashboardDialogComponent} from "./dialogs/edit-dashboard/edit-dashboard-dialog.component";
+import {DashboardGridComponent} from "./components/grid/dashboard-grid.component";
 
 const dashboardWidgets = [
 
@@ -45,6 +46,7 @@ const dashboardWidgets = [
     ],
     declarations: [
         DashboardComponent,
+        DashboardGridComponent,
         DashboardOverviewComponent,
         DashboardPanelComponent,
         DashboardWidgetComponent,
diff --git a/ui/src/app/dashboard-v2/models/widget-data.model.ts b/ui/src/app/dashboard-v2/models/widget-data.model.ts
deleted file mode 100644
index ca69adc..0000000
--- a/ui/src/app/dashboard-v2/models/widget-data.model.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-
-export interface WidgetData {
-    name?: string;
-    label?: string;
-    icon?: string;
-}
\ No newline at end of file