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 <rie...@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);

Reply via email to