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/06/07 21:05:56 UTC
[incubator-streampipes] 02/02: [STREAMPIPES-145] Add dialog template
This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch STREAMPIPES-145
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
commit 6e85d52a5b714b71814219fd07858e6f000ddc5d
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sun Jun 7 23:05:40 2020 +0200
[STREAMPIPES-145] Add dialog template
---
.../pipeline-assembly.component.html | 3 -
.../components/pipeline/pipeline.component.ts | 51 ++++++++----
.../dialog/customize/customize.component.css | 0
.../dialog/customize/customize.component.html | 18 ++++
.../customize/customize.component.ts} | 27 +++---
.../panel/dialog-ref.ts} | 33 +++++---
.../dialog/panel/panel-dialog.component.html | 23 +++++
.../panel/panel-dialog.component.scss} | 26 +++---
.../dialog/panel/panel-dialog.component.ts | 67 +++++++++++++++
.../editor-v2/dialog/panel/panel-dialog.service.ts | 97 ++++++++++++++++++++++
ui/src/app/editor-v2/editor.module.ts | 13 ++-
ui/src/app/editor-v2/model/editor.model.ts | 12 ++-
ui/src/app/editor-v2/services/editor.service.ts | 28 ++++++-
ui/src/app/editor-v2/services/jsplumb.service.ts | 19 ++++-
.../editor-v2/services/object-provider.service.ts | 6 +-
ui/src/app/services/rest-api.service.ts | 8 --
16 files changed, 364 insertions(+), 67 deletions(-)
diff --git a/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.html b/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.html
index 67dd075..5680b95 100644
--- a/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.html
+++ b/ui/src/app/editor-v2/components/pipeline-assembly/pipeline-assembly.component.html
@@ -90,9 +90,6 @@
<button mat-button matTooltip="Clear Assembly Area" [matTooltipPosition]="'above'"
class="md-icon-button" (click)="showClearAssemblyConfirmDialog($event)">
<i class="material-icons">clear</i>
- <!-- <md-tooltip md-direction="top">-->
- <!-- Clear Assembly Area-->
- <!-- </md-tooltip>-->
</button>
</div>
</div>
diff --git a/ui/src/app/editor-v2/components/pipeline/pipeline.component.ts b/ui/src/app/editor-v2/components/pipeline/pipeline.component.ts
index 2b56f80..be53fe5 100644
--- a/ui/src/app/editor-v2/components/pipeline/pipeline.component.ts
+++ b/ui/src/app/editor-v2/components/pipeline/pipeline.component.ts
@@ -24,18 +24,22 @@ import {JsplumbService} from "../../services/jsplumb.service";
import {PipelineEditorService} from "../../services/pipeline-editor.service";
import {JsplumbBridge} from "../../services/jsplumb-bridge.service";
import {ShepherdService} from "../../../services/tour/shepherd.service";
-import {Component, Input, OnInit, Pipe} from "@angular/core";
+import {Component, InjectionToken, Input, OnInit, Pipe} from "@angular/core";
import {
- InvocablePipelineElementUnion,
+ InvocablePipelineElementUnion, PIPELINE_ELEMENT_TOKEN,
PipelineElementConfig,
PipelineElementUnion
} from "../../model/editor.model";
import {
+ CustomOutputStrategy,
DataProcessorInvocation,
Pipeline,
SpDataStream
} from "../../../core-model/gen/streampipes-model";
import {ObjectProvider} from "../../services/object-provider.service";
+import {PanelDialogService} from "../../dialog/panel/panel-dialog.service";
+import {CustomizeComponent} from "../../dialog/customize/customize.component";
+import {DialogRef} from "../../dialog/panel/dialog-ref";
@Component({
selector: 'pipeline',
@@ -87,7 +91,8 @@ export class PipelineComponent implements OnInit {
// TransitionService,
private ShepherdService: ShepherdService,
private PipelineValidationService: PipelineValidationService,
- private RestApi: RestApi) {
+ private RestApi: RestApi,
+ private PanelDialogService: PanelDialogService) {
this.plumbReady = false;
this.currentMouseOverElement = "";
this.currentPipelineModel = new Pipeline();
@@ -281,26 +286,19 @@ export class PipelineComponent implements OnInit {
var pe = this.ObjectProvider.findElement(info.target.id, this.rawPipelineModel);
if (pe.settings.openCustomize) {
this.currentPipelineModel = this.ObjectProvider.makePipeline(this.rawPipelineModel);
- console.log(this.currentPipelineModel);
pe.settings.loadingStatus = true;
this.ObjectProvider.updatePipeline(this.currentPipelineModel)
- .then(msg => {
- let data = msg.data;
+ .subscribe(pipelineModificationMessage => {
pe.settings.loadingStatus = false;
- if (data.success) {
+ if (pipelineModificationMessage.success) {
info.targetEndpoint.setType("token");
this.validatePipeline();
- this.modifyPipeline(data.pipelineModifications);
+ this.modifyPipeline(pipelineModificationMessage.pipelineModifications);
var sourceEndpoint = this.JsplumbBridge.selectEndpoints({element: info.targetEndpoint.elementId});
if (this.PipelineEditorService.isFullyConnected(pe)) {
let payload = pe.payload as InvocablePipelineElementUnion;
if ((payload.staticProperties && payload.staticProperties.length > 0) || this.isCustomOutput(pe)) {
- this.EditorDialogManager.showCustomizeDialog($("#" +pe.payload.dom), sourceEndpoint, pe.payload, false)
- .then(() => {
- this.JsplumbService.activateEndpoint(pe.payload.dom, !payload.uncompleted);
- }, () => {
- this.JsplumbService.activateEndpoint(pe.payload.dom, !payload.uncompleted);
- });
+ this.showCustomizeDialog(pe);
} else {
//this.$rootScope.$broadcast("SepaElementConfigured", pe.payload.DOM);
(pe.payload as InvocablePipelineElementUnion).configured = true;
@@ -308,7 +306,7 @@ export class PipelineComponent implements OnInit {
}
} else {
this.JsplumbBridge.detach(info.connection);
- this.EditorDialogManager.showMatchingErrorDialog(data);
+ this.EditorDialogManager.showMatchingErrorDialog(pipelineModificationMessage);
}
});
}
@@ -338,7 +336,7 @@ export class PipelineComponent implements OnInit {
isCustomOutput(pe) {
var custom = false;
angular.forEach(pe.payload.outputStrategies, strategy => {
- if (strategy.type == 'org.apache.streampipes.model.output.CustomOutputStrategy') {
+ if (strategy instanceof CustomOutputStrategy) {
custom = true;
}
});
@@ -353,5 +351,26 @@ export class PipelineComponent implements OnInit {
});
}
+ showCustomizeDialog(pipelineElement: PipelineElementConfig) {
+ const inputMap = {};
+ inputMap["pipelineElement"] = pipelineElement;
+
+ const dialogRef = this.PanelDialogService.open(CustomizeComponent, {
+ width: "400px",
+ title: "Customize " + pipelineElement.payload.name
+ }, inputMap);
+
+ dialogRef.afterClosed().subscribe(c => {
+
+ });
+
+ // this.EditorDialogManager.showCustomizeDialog($("#" +pe.payload.dom), sourceEndpoint, pe.payload, false)
+ // .then(() => {
+ // this.JsplumbService.activateEndpoint(pe.payload.dom, !payload.uncompleted);
+ // }, () => {
+ // this.JsplumbService.activateEndpoint(pe.payload.dom, !payload.uncompleted);
+ // });
+ }
+
}
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/dialog/customize/customize.component.css b/ui/src/app/editor-v2/dialog/customize/customize.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/ui/src/app/editor-v2/dialog/customize/customize.component.html b/ui/src/app/editor-v2/dialog/customize/customize.component.html
new file mode 100644
index 0000000..e40d375
--- /dev/null
+++ b/ui/src/app/editor-v2/dialog/customize/customize.component.html
@@ -0,0 +1,18 @@
+<!--
+ ~ 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.
+ ~
+ -->
+
diff --git a/ui/src/app/editor-v2/services/editor.service.ts b/ui/src/app/editor-v2/dialog/customize/customize.component.ts
similarity index 61%
copy from ui/src/app/editor-v2/services/editor.service.ts
copy to ui/src/app/editor-v2/dialog/customize/customize.component.ts
index 42f8cc2..9e9811b 100644
--- a/ui/src/app/editor-v2/services/editor.service.ts
+++ b/ui/src/app/editor-v2/dialog/customize/customize.component.ts
@@ -16,19 +16,26 @@
*
*/
-import {Injectable} from "@angular/core";
-import {HttpClient} from "@angular/common/http";
-import {AuthStatusService} from "../../services/auth-status.service";
-import {TsonLdSerializerService} from "../../platform-services/tsonld-serializer.service";
+import {Component, Input, OnInit} from "@angular/core";
+import {PipelineElementConfig} from "../../model/editor.model";
+import {DialogRef} from "../panel/dialog-ref";
-@Injectable()
-export class EditorService {
+@Component({
+ selector: 'customize-pipeline-element',
+ templateUrl: './customize.component.html',
+ styleUrls: ['./customize.component.css']
+})
+export class CustomizeComponent implements OnInit {
- constructor(private http: HttpClient,
- private authStatusService: AuthStatusService,
- private tsonLdSerializerService: TsonLdSerializerService) {
- }
+ @Input()
+ pipelineElement: PipelineElementConfig;
+ constructor(private dialogRef: DialogRef<CustomizeComponent>) {
+ }
+
+ ngOnInit(): void {
+
+ }
}
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/services/editor.service.ts b/ui/src/app/editor-v2/dialog/panel/dialog-ref.ts
similarity index 56%
copy from ui/src/app/editor-v2/services/editor.service.ts
copy to ui/src/app/editor-v2/dialog/panel/dialog-ref.ts
index 42f8cc2..9cf9e6a 100644
--- a/ui/src/app/editor-v2/services/editor.service.ts
+++ b/ui/src/app/editor-v2/dialog/panel/dialog-ref.ts
@@ -16,19 +16,32 @@
*
*/
-import {Injectable} from "@angular/core";
-import {HttpClient} from "@angular/common/http";
-import {AuthStatusService} from "../../services/auth-status.service";
-import {TsonLdSerializerService} from "../../platform-services/tsonld-serializer.service";
+import {ComponentRef} from "@angular/core";
+import {OverlayRef} from "@angular/cdk/overlay";
+import {Observable, Subject} from "rxjs";
-@Injectable()
-export class EditorService {
+export class DialogRef<T> {
+ private _componentInstance: ComponentRef<T>;
+ private subject: Subject<any> = new Subject<any>();
- constructor(private http: HttpClient,
- private authStatusService: AuthStatusService,
- private tsonLdSerializerService: TsonLdSerializerService) {
- }
+ constructor(private overlayRef: OverlayRef) {
+ }
+ get componentInstance() {
+ return this._componentInstance;
+ }
+ set componentInstance(c: ComponentRef<T>) {
+ this._componentInstance = c;
+ }
+
+ public close(data?: any) {
+ this.overlayRef.dispose();
+ this.subject.next(data);
+ }
+
+ public afterClosed(): Observable<any> {
+ return this.subject;
+ }
}
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/dialog/panel/panel-dialog.component.html b/ui/src/app/editor-v2/dialog/panel/panel-dialog.component.html
new file mode 100644
index 0000000..23c2f5f
--- /dev/null
+++ b/ui/src/app/editor-v2/dialog/panel/panel-dialog.component.html
@@ -0,0 +1,23 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<div style="display:flex;justify-content:space-between;padding:0.5rem;width:100%">
+ <span class="dialog-title">{{ dialogTitle }}</span>
+ <button mat-button mat-icon-button (click)="closeDialog()"><i class="material-icons">clear</i></button>
+</div>
+<ng-template cdkPortalOutlet #portal></ng-template>
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/services/editor.service.ts b/ui/src/app/editor-v2/dialog/panel/panel-dialog.component.scss
similarity index 62%
copy from ui/src/app/editor-v2/services/editor.service.ts
copy to ui/src/app/editor-v2/dialog/panel/panel-dialog.component.scss
index 42f8cc2..cdeec74 100644
--- a/ui/src/app/editor-v2/services/editor.service.ts
+++ b/ui/src/app/editor-v2/dialog/panel/panel-dialog.component.scss
@@ -16,19 +16,19 @@
*
*/
-import {Injectable} from "@angular/core";
-import {HttpClient} from "@angular/common/http";
-import {AuthStatusService} from "../../services/auth-status.service";
-import {TsonLdSerializerService} from "../../platform-services/tsonld-serializer.service";
-
-@Injectable()
-export class EditorService {
-
- constructor(private http: HttpClient,
- private authStatusService: AuthStatusService,
- private tsonLdSerializerService: TsonLdSerializerService) {
- }
-
+@import '../../../../scss/sp/colors';
+app-dialog-container {
+ width: 100%;
+ display: grid;
+ grid-template-rows: 40px 1fr;
+ padding: 0 10px;
+ background-color: #fff
+}
+.dialog-title {
+ font-weight: bold;
+ background: $sp-color-primary;
+ padding:20px;
+ color:white;
}
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/dialog/panel/panel-dialog.component.ts b/ui/src/app/editor-v2/dialog/panel/panel-dialog.component.ts
new file mode 100644
index 0000000..2ba2715
--- /dev/null
+++ b/ui/src/app/editor-v2/dialog/panel/panel-dialog.component.ts
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import {CdkPortalOutlet, ComponentPortal, Portal} from "@angular/cdk/portal";
+import {
+ Component,
+ EventEmitter,
+ Input,
+ OnInit,
+ Output,
+ ViewChild,
+ ViewEncapsulation
+} from "@angular/core";
+
+@Component({
+ selector: "app-dialog-container",
+ templateUrl: './panel-dialog.component.html',
+ encapsulation: ViewEncapsulation.None,
+ styleUrls: ['./panel-dialog.component.scss']
+})
+export class PanelDialogComponent<T> implements OnInit {
+
+ @Input()
+ dialogTitle = "";
+
+ @Input()
+ comp: ComponentPortal<T>;
+
+ @Output()
+ containerEvent = new EventEmitter<{ key: "CLOSE" }>();
+
+ @ViewChild("portal", {read: CdkPortalOutlet, static: true})
+ portal: CdkPortalOutlet;
+
+ @Input()
+ selectedPortal: Portal<T>;
+
+ constructor() {
+ }
+
+ ngOnInit() {
+ }
+
+ attach() {
+ const c = this.portal.attach(this.selectedPortal);
+ return c.instance;
+ }
+
+ closeDialog() {
+ this.containerEvent.emit({key: "CLOSE"});
+ }
+}
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/dialog/panel/panel-dialog.service.ts b/ui/src/app/editor-v2/dialog/panel/panel-dialog.service.ts
new file mode 100644
index 0000000..69947ac
--- /dev/null
+++ b/ui/src/app/editor-v2/dialog/panel/panel-dialog.service.ts
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import {ComponentType, Overlay, OverlayRef,} from "@angular/cdk/overlay";
+import {ComponentPortal, PortalInjector,} from "@angular/cdk/portal";
+import {PanelDialogComponent} from "./panel-dialog.component";
+import {DialogConfig} from "../../model/editor.model";
+import {ComponentRef, Injectable, Injector} from "@angular/core";
+import {DialogRef} from "./dialog-ref";
+
+@Injectable({
+ providedIn: "root"
+})
+export class PanelDialogService {
+
+ constructor(private overlay: Overlay, private injector: Injector) {
+
+ }
+
+ public open<T>(component: ComponentType<T>,
+ config?: DialogConfig,
+ inputMap?: Object): DialogRef<T> {
+ config = config || {width: "auto", title: ""};
+
+ const positionStrategy = this.overlay
+ .position()
+ .global()
+ .top("0")
+ .right("0");
+
+ const overlay = this.overlay.create({
+ hasBackdrop: true,
+ positionStrategy,
+ panelClass: "dialog-container",
+ width: config.width,
+ maxWidth: "90vw",
+ height: "100vh"
+ });
+
+ const dialogPreview = new ComponentPortal(PanelDialogComponent);
+ const dialogContainerRef = overlay.attach(dialogPreview);
+ dialogContainerRef.instance.dialogTitle = config.title;
+ const dialogRef = new DialogRef<T>(overlay);
+
+ const injector = this.createInjector(dialogRef);
+ dialogContainerRef.instance.selectedPortal = new ComponentPortal(component,
+ null, injector);
+ dialogRef.componentInstance = dialogContainerRef.instance.attach();
+
+ Object.keys(inputMap).forEach(key => {
+ dialogRef.componentInstance[key] = inputMap[key];
+ })
+
+ this.applyDialogProperties(dialogContainerRef, overlay, config);
+
+ return dialogRef;
+ }
+
+ private applyDialogProperties(componentRef: ComponentRef<any>,
+ overlayRef: OverlayRef,
+ config: DialogConfig
+ ) {
+ componentRef.instance.containerEvent.subscribe(e => {
+ if (e.key === "CLOSE") {
+ overlayRef.dispose();
+ }
+ });
+ if (!config.disableClose) {
+ overlayRef.backdropClick().subscribe(() => overlayRef.dispose());
+ }
+ }
+
+ private createInjector<T>(dialogRef: DialogRef<T>) {
+ const injectorMap = new WeakMap();
+ injectorMap.set(DialogRef, dialogRef);
+ return new PortalInjector(this.injector, injectorMap);
+ }
+}
+
+
+
+
diff --git a/ui/src/app/editor-v2/editor.module.ts b/ui/src/app/editor-v2/editor.module.ts
index 25bfd62..936e1f2 100644
--- a/ui/src/app/editor-v2/editor.module.ts
+++ b/ui/src/app/editor-v2/editor.module.ts
@@ -43,6 +43,11 @@ import {PipelineComponent} from "./components/pipeline/pipeline.component";
import {ObjectProvider} from "./services/object-provider.service";
import {PipelineElementOptionsComponent} from "./components/pipeline-element-options/pipeline-element-options.component";
import {PipelineElementRecommendationService} from "./services/pipeline-element-recommendation.service";
+import {PortalModule} from "@angular/cdk/portal";
+import {OverlayModule} from "@angular/cdk/overlay";
+import {PanelDialogComponent} from "./dialog/panel/panel-dialog.component";
+import {PanelDialogService} from "./dialog/panel/panel-dialog.service";
+import {CustomizeComponent} from "./dialog/customize/customize.component";
@NgModule({
imports: [
@@ -55,14 +60,18 @@ import {PipelineElementRecommendationService} from "./services/pipeline-element-
CustomMaterialModule,
FormsModule,
ConnectModule,
+ PortalModule,
+ OverlayModule
],
declarations: [
+ CustomizeComponent,
EditorComponent,
PipelineAssemblyComponent,
PipelineElementIconStandComponent,
PipelineElementComponent,
PipelineElementOptionsComponent,
- PipelineComponent
+ PipelineComponent,
+ PanelDialogComponent
],
providers: [
EditorService,
@@ -76,6 +85,7 @@ import {PipelineElementRecommendationService} from "./services/pipeline-element-
JsplumbService,
JsplumbConfigService,
ObjectProvider,
+ PanelDialogService,
PipelineEditorService,
PipelinePositioningService,
PipelineValidationService,
@@ -98,6 +108,7 @@ import {PipelineElementRecommendationService} from "./services/pipeline-element-
],
entryComponents: [
EditorComponent,
+ PanelDialogComponent
]
})
export class EditorModule {
diff --git a/ui/src/app/editor-v2/model/editor.model.ts b/ui/src/app/editor-v2/model/editor.model.ts
index 025fbdc..9a98ce9 100644
--- a/ui/src/app/editor-v2/model/editor.model.ts
+++ b/ui/src/app/editor-v2/model/editor.model.ts
@@ -22,6 +22,7 @@ import {
SpDataStream
} from "../../core-model/gen/streampipes-model";
import {EditorConstants} from "../constants/editor.constants";
+import {InjectionToken} from "@angular/core";
export type PipelineElementHolder = {
[key: string]: Array<PipelineElementUnion>;
@@ -51,6 +52,15 @@ export enum PipelineElementType {
DataSink
}
+export interface DialogConfig {
+ width?: string;
+ disableClose?: boolean;
+ autoFocus?: boolean;
+ title: string;
+}
+
export type PipelineElementUnion = SpDataSet | SpDataStream | DataProcessorInvocation | DataSinkInvocation;
-export type InvocablePipelineElementUnion = DataProcessorInvocation | DataSinkInvocation;
\ No newline at end of file
+export type InvocablePipelineElementUnion = DataProcessorInvocation | DataSinkInvocation;
+
+export const PIPELINE_ELEMENT_TOKEN = new InjectionToken<{}>('pipelineElement');
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/services/editor.service.ts b/ui/src/app/editor-v2/services/editor.service.ts
index 42f8cc2..309c386 100644
--- a/ui/src/app/editor-v2/services/editor.service.ts
+++ b/ui/src/app/editor-v2/services/editor.service.ts
@@ -20,13 +20,37 @@ import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {AuthStatusService} from "../../services/auth-status.service";
import {TsonLdSerializerService} from "../../platform-services/tsonld-serializer.service";
+import {
+ DataProcessorInvocation, PipelineElementRecommendationMessage,
+ PipelineModificationMessage
+} from "../../core-model/gen/streampipes-model";
+import {Observable} from "rxjs";
@Injectable()
export class EditorService {
constructor(private http: HttpClient,
- private authStatusService: AuthStatusService,
- private tsonLdSerializerService: TsonLdSerializerService) {
+ private authStatusService: AuthStatusService) {
+ }
+
+ recommendPipelineElement(pipeline): Observable<PipelineElementRecommendationMessage> {
+ return this.http.post(this.pipelinesResourceUrl +"/recommend", pipeline)
+ .map(data => PipelineElementRecommendationMessage.fromData(data as any));
+ }
+
+ updatePartialPipeline(pipeline): Observable<PipelineModificationMessage> {
+ return this.http.post(this.pipelinesResourceUrl +"/update", pipeline)
+ .map(data => {
+ return PipelineModificationMessage.fromData(data as any);
+ });
+ }
+
+ private get baseUrl() {
+ return '/streampipes-backend';
+ }
+
+ private get pipelinesResourceUrl() {
+ return this.baseUrl + '/api/v2/users/' + this.authStatusService.email + '/pipelines'
}
diff --git a/ui/src/app/editor-v2/services/jsplumb.service.ts b/ui/src/app/editor-v2/services/jsplumb.service.ts
index e91e841..2c773e5 100644
--- a/ui/src/app/editor-v2/services/jsplumb.service.ts
+++ b/ui/src/app/editor-v2/services/jsplumb.service.ts
@@ -22,6 +22,11 @@ import {Inject, Injectable} from "@angular/core";
import {PipelineElementConfig, PipelineElementUnion} from "../model/editor.model";
import {PipelineElementTypeUtils} from "../utils/editor.utils";
import * as angular from "angular";
+import {
+ DataProcessorInvocation, DataSinkInvocation,
+ SpDataSet,
+ SpDataStream
+} from "../../core-model/gen/streampipes-model";
@Injectable()
export class JsplumbService {
@@ -147,7 +152,7 @@ export class JsplumbService {
let pipelineElementConfig = {} as PipelineElementConfig;
pipelineElementConfig.type = PipelineElementTypeUtils
.toCssShortHand(PipelineElementTypeUtils.fromType(pipelineElement))
- pipelineElementConfig.payload = angular.copy(pipelineElement)
+ pipelineElementConfig.payload = this.clone(pipelineElement);
pipelineElementConfig.settings = {connectable: connectable,
openCustomize: !(pipelineElement as any).configured,
preview: isPreview,
@@ -166,6 +171,18 @@ export class JsplumbService {
return pipelineElementConfig;
}
+ clone(pipelineElement: PipelineElementUnion) {
+ if (pipelineElement instanceof SpDataSet) {
+ return SpDataSet.fromData(pipelineElement, new SpDataSet());
+ } else if (pipelineElement instanceof SpDataStream) {
+ return SpDataStream.fromData(pipelineElement, new SpDataStream());
+ } else if (pipelineElement instanceof DataProcessorInvocation) {
+ return DataProcessorInvocation.fromData(pipelineElement, new DataProcessorInvocation());
+ } else {
+ return DataSinkInvocation.fromData(pipelineElement, new DataSinkInvocation());
+ }
+ }
+
makeId(count) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
diff --git a/ui/src/app/editor-v2/services/object-provider.service.ts b/ui/src/app/editor-v2/services/object-provider.service.ts
index bd07a51..bbf1cff 100644
--- a/ui/src/app/editor-v2/services/object-provider.service.ts
+++ b/ui/src/app/editor-v2/services/object-provider.service.ts
@@ -22,12 +22,14 @@ import {RestApi} from "../../services/rest-api.service";
import {JsplumbBridge} from "./jsplumb-bridge.service";
import {InvocablePipelineElementUnion, PipelineElementConfig} from "../model/editor.model";
import {InvocableStreamPipesEntity, Pipeline} from "../../core-model/gen/streampipes-model";
+import {EditorService} from "./editor.service";
@Injectable()
export class ObjectProvider {
constructor(private RestApi: RestApi,
- private JsplumbBridge: JsplumbBridge) {
+ private JsplumbBridge: JsplumbBridge,
+ private EditorService: EditorService) {
}
prepareElement(pipelineElement: InvocablePipelineElementUnion) {
@@ -91,7 +93,7 @@ export class ObjectProvider {
}
updatePipeline(pipeline: Pipeline) {
- return this.RestApi.updatePartialPipeline(pipeline);
+ return this.EditorService.updatePartialPipeline(pipeline);
};
storePipeline(pipeline) {
diff --git a/ui/src/app/services/rest-api.service.ts b/ui/src/app/services/rest-api.service.ts
index bceb0bd..ad9491e 100644
--- a/ui/src/app/services/rest-api.service.ts
+++ b/ui/src/app/services/rest-api.service.ts
@@ -268,15 +268,7 @@ export class RestApi {
return this.$http.post(this.urlBase() +"/pe/options", resolvableOptionsParameterRequest);
}
- recommendPipelineElement(pipeline) {
- return this.$http.post(this.urlBase() +"/pipelines/recommend", pipeline);
- }
- updatePartialPipeline(pipeline) {
- return this.$http.post(this.urlBase() +"/pipelines/update", pipeline, {
- ignoreLoadingBar: true
- });
- }
updateDataSet(dataSet) {
return this.$http.post(this.urlBase() +"/pipelines/update/dataset", dataSet);