You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2021/03/09 21:50:04 UTC
[incubator-streampipes] 02/06: [STREAMPIPES-304] Bump and migrate
Jsplumb version
This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
commit f24b1b4a3ad14203803b8d71c3eb80354f61a39c
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sun Mar 7 21:37:21 2021 +0100
[STREAMPIPES-304] Bump and migrate Jsplumb version
---
ui/angular.json | 1 -
ui/package.json | 3 +-
.../pipeline-assembly.component.html | 9 +-
.../pipeline-assembly.component.scss | 18 +-
.../pipeline-assembly.component.ts | 32 +++-
.../pipeline-element-options.component.ts | 8 +-
.../components/pipeline/pipeline.component.html | 10 +-
.../components/pipeline/pipeline.component.ts | 79 +++++---
ui/src/app/editor/editor.module.ts | 17 +-
.../filter/enabled-pipeline-element.filter.ts | 15 ++
ui/src/app/editor/model/editor.model.ts | 7 +-
ui/src/app/editor/model/jsplumb.model.ts | 26 +++
.../app/editor/services/jsplumb-bridge.service.ts | 79 +++++---
.../app/editor/services/jsplumb-config.service.ts | 48 ++---
.../editor/services/jsplumb-endpoint.service.ts | 63 +++++++
.../app/editor/services/jsplumb-factory.service.ts | 85 +++++++++
ui/src/app/editor/services/jsplumb.service.ts | 210 +++++++++------------
.../app/editor/services/object-provider.service.ts | 24 ++-
.../services/pipeline-canvas-scrolling.service.ts | 35 ++++
.../app/editor/services/pipeline-editor.service.ts | 19 +-
.../services/pipeline-element-dragged.service.ts | 31 +++
.../pipeline-element-recommendation.service.ts | 8 +-
.../services/pipeline-positioning.service.ts | 124 ++++++------
.../editor/services/pipeline-validation.service.ts | 42 ++---
.../preview/pipeline-preview.component.ts | 8 +-
ui/src/scss/main.scss | 4 +-
ui/src/scss/sp/jsplumb.scss | 21 +++
ui/src/scss/sp/main.scss | 8 +-
28 files changed, 694 insertions(+), 340 deletions(-)
diff --git a/ui/angular.json b/ui/angular.json
index 42cdf7b..c1ae092 100644
--- a/ui/angular.json
+++ b/ui/angular.json
@@ -39,7 +39,6 @@
"node_modules/datatables.net/js/jquery.dataTables.js",
"node_modules/jquery.panzoom/dist/jquery.panzoom.js",
"node_modules/jquery-ui-dist/jquery-ui.js",
- "node_modules/jsplumb/dist/js/jsPlumb-2.1.3-min.js",
"node_modules/quill/dist/quill.js",
]
},
diff --git a/ui/package.json b/ui/package.json
index ad82c27..8d3a3b9 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -60,7 +60,7 @@
"jquery-ui-dist": "1.12.1",
"jquery.panzoom": "2.0.5",
"jshint": "2.11.1",
- "jsplumb": "2.1.3",
+ "jsplumb": "^2.15.5",
"jszip": "3.2.1",
"konva": "3.2.4",
"leaflet": "1.6.0",
@@ -74,6 +74,7 @@
"ngx-auto-scroll": "^1.1.0",
"ngx-color-picker": "9.0.0",
"ngx-echarts": "^6.0.0",
+ "ngx-perfect-scrollbar": "^10.1.0",
"ngx-quill": "12.0.1",
"ngx-showdown": "5.1.0",
"path": "^0.12.7",
diff --git a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.html b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.html
index f2424b9..1eddb4e 100644
--- a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.html
+++ b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.html
@@ -20,10 +20,9 @@
<div class="pipeline-assembly-options sp-blue-bg">
<div fxFlex="100" fxLayout="row" fxLayoutAlign="start center">
<button mat-button matTooltip="Save Pipeline" [matTooltipPosition]="'above'"
- style="display:flex;align-items:center;"
[disabled]="!PipelineValidationService.pipelineValid"
(click)="submit()" type="submit">
- <mat-icon>save</mat-icon> <span>Save pipeline</span>
+ <i class="material-icons">save</i> <span>Save pipeline</span>
</button>
<button mat-button mat-icon-button matTooltip="Pan" [matTooltipPosition]="'above'"
[disabled]="!selectMode"
@@ -103,7 +102,7 @@
</div>
</div>
<div id="outerAssemblyArea" class="outerAssembly sp-blue-border-nopadding">
- <div id="assembly" class="canvas">
+ <div id="assembly" class="canvas jtk-surface jtk-surface-no-pan">
<pipeline [pipelineValid]="pipelineValid"
[canvasId]="'assembly'"
[rawPipelineModel]="rawPipelineModel"
@@ -112,8 +111,8 @@
[pipelineCached]="pipelineCached"
[pipelineCacheRunning]="pipelineCacheRunning"
(pipelineCachedChanged)="pipelineCached=$event"
- (pipelineCacheRunningChanged)="pipelineCacheRunning=$event"
- ></pipeline>
+ (pipelineCacheRunningChanged)="pipelineCacheRunning=$event">
+ </pipeline>
</div>
</div>
</div>
diff --git a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
index d252c0d..5bbd778 100644
--- a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
+++ b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
@@ -30,13 +30,12 @@
}
.outerAssembly {
- position: relative;
+ //position: relative;
left: 0px;
top: 0px;
overflow: visible;
//box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .2), 0 1px 1px 0 rgba(0, 0, 0, .14), 0 2px 1px -1px rgba(0, 0, 0, .12);
- padding: 5px;
- height: 100%;
+ //padding: 5px;
flex: 1;
width: 100%;
}
@@ -46,12 +45,12 @@
}
.canvas {
- overflow: visible;
- position: absolute;
+ overflow: auto;
+ position: relative;
left: 0px;
top: 0px;
- height: 300%;
- width: 300%;
+ height: 100%;
+ width: 100%;
z-index: 0;
margin: -1px;
@@ -63,3 +62,8 @@
.pipeline-assembly-options {
color: white;
}
+
+.jtk-surface-nopan {
+ overflow: scroll !important;
+ cursor:default;
+}
diff --git a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.ts b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.ts
index 6979f0e..8b44161 100644
--- a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.ts
+++ b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.ts
@@ -16,7 +16,16 @@
*
*/
-import {Component, EventEmitter, Input, NgZone, OnInit, Output,} from "@angular/core";
+import {
+ Component,
+ ElementRef,
+ EventEmitter,
+ Input,
+ NgZone,
+ OnInit,
+ Output,
+ ViewChild,
+} from "@angular/core";
import {JsplumbBridge} from "../../services/jsplumb-bridge.service";
import {PipelinePositioningService} from "../../services/pipeline-positioning.service";
import {PipelineValidationService} from "../../services/pipeline-validation.service";
@@ -31,6 +40,8 @@ import {ConfirmDialogComponent} from "../../../core-ui/dialog/confirm-dialog/con
import {MatDialog} from "@angular/material/dialog";
import {EditorService} from "../../services/editor.service";
import {PipelineService} from "../../../platform-services/apis/pipeline.service";
+import {PipelineCanvasScrollingService} from "../../services/pipeline-canvas-scrolling.service";
+import {JsplumbFactoryService} from "../../services/jsplumb-factory.service";
@Component({
@@ -52,6 +63,8 @@ export class PipelineAssemblyComponent implements OnInit {
@Output()
pipelineCanvasMaximizedEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
+ JsplumbBridge: JsplumbBridge;
+
pipelineCanvasMaximized: boolean = false;
currentMouseOverElement: any;
@@ -69,7 +82,10 @@ export class PipelineAssemblyComponent implements OnInit {
pipelineCacheRunning: boolean = false;
pipelineCached: boolean = false;
- constructor(private JsplumbBridge: JsplumbBridge,
+ config: any = {};
+ @ViewChild("assembly") pipelineCanvas: ElementRef;
+
+ constructor(private JsPlumbFactoryService: JsplumbFactoryService,
private PipelinePositioningService: PipelinePositioningService,
private ObjectProvider: ObjectProvider,
public EditorService: EditorService,
@@ -79,7 +95,8 @@ export class PipelineAssemblyComponent implements OnInit {
private ShepherdService: ShepherdService,
private dialogService: DialogService,
private dialog: MatDialog,
- private ngZone: NgZone) {
+ private ngZone: NgZone,
+ private pipelineCanvasScrollingService: PipelineCanvasScrollingService) {
this.selectMode = true;
this.currentZoomLevel = 1;
@@ -87,11 +104,18 @@ export class PipelineAssemblyComponent implements OnInit {
}
ngOnInit(): void {
+ this.JsplumbBridge = this.JsPlumbFactoryService.getJsplumbBridge(false);
if (this.currentModifiedPipelineId) {
this.displayPipelineById();
} else {
this.checkAndDisplayCachedPipeline();
}
+ this.pipelineCanvasScrollingService.canvasScrollYSubject.subscribe(position => {
+ console.log("scrolling to" + position);
+ console.log(this.pipelineCanvas.nativeElement.scrollHeight);
+ console.log(this.pipelineCanvas.nativeElement.scrollTop);
+ this.pipelineCanvas.nativeElement.scrollTop = this.pipelineCanvas.nativeElement.scrollHeight;
+ });
}
ngAfterViewInit() {
@@ -231,7 +255,7 @@ export class PipelineAssemblyComponent implements OnInit {
this.EditorService.makePipelineAssemblyEmpty(false);
this.ngZone.run(() => {
this.pipelineValid = this.PipelineValidationService
- .isValidPipeline(this.rawPipelineModel.filter(pe => !(pe.settings.disabled)));
+ .isValidPipeline(this.rawPipelineModel.filter(pe => !(pe.settings.disabled)), false);
});
});
}
diff --git a/ui/src/app/editor/components/pipeline-element-options/pipeline-element-options.component.ts b/ui/src/app/editor/components/pipeline-element-options/pipeline-element-options.component.ts
index 6d20d18..4c89316 100644
--- a/ui/src/app/editor/components/pipeline-element-options/pipeline-element-options.component.ts
+++ b/ui/src/app/editor/components/pipeline-element-options/pipeline-element-options.component.ts
@@ -36,6 +36,7 @@ import {CompatibleElementsComponent} from "../../dialog/compatible-elements/comp
import {Tuple2} from "../../../core-model/base/Tuple2";
import { cloneDeep } from "lodash";
import {Observable, Subscription} from "rxjs";
+import {JsplumbFactoryService} from "../../services/jsplumb-factory.service";
@Component({
selector: 'pipeline-element-options',
@@ -79,11 +80,13 @@ export class PipelineElementOptionsComponent implements OnInit, OnDestroy {
pipelineElementConfiguredObservable: Subscription;
+ JsplumbBridge: JsplumbBridge;
+
constructor(private ObjectProvider: ObjectProvider,
private PipelineElementRecommendationService: PipelineElementRecommendationService,
private DialogService: DialogService,
private EditorService: EditorService,
- private JsplumbBridge: JsplumbBridge,
+ private JsplumbFactoryService: JsplumbFactoryService,
private JsplumbService: JsplumbService,
private PipelineValidationService: PipelineValidationService,
private RestApi: RestApi) {
@@ -91,6 +94,7 @@ export class PipelineElementOptionsComponent implements OnInit, OnDestroy {
this.possibleElements = [];
this.recommendedElements = [];
this.recommendationsShown = false;
+ this.JsplumbBridge = this.JsplumbFactoryService.getJsplumbBridge(false);
}
ngOnInit() {
@@ -187,4 +191,4 @@ export class PipelineElementOptionsComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this.pipelineElementConfiguredObservable.unsubscribe();
}
-}
\ No newline at end of file
+}
diff --git a/ui/src/app/editor/components/pipeline/pipeline.component.html b/ui/src/app/editor/components/pipeline/pipeline.component.html
index fbcd494..b3736fa 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.component.html
+++ b/ui/src/app/editor/components/pipeline/pipeline.component.html
@@ -16,10 +16,12 @@
~
-->
-<div *ngFor="let pipelineElement of rawPipelineModel" style="width:100%;height:100%;z-index:1">
- <div *ngIf="pipelineElement.settings.disabled == undefined || !pipelineElement.settings.disabled" style="width:100%;height:100%;z-index:1">
+<div style="z-index: 1" [ngStyle]="{width: canvasWidth, height: canvasHeight}" #outerCanvas>
<span id="{{pipelineElement.payload.dom}}" style="{{getElementCss(pipelineElement.settings)}}"
- (click)="updateOptionsClick(pipelineElement.payload.dom)" (mouseenter)="updateMouseover(pipelineElement.payload.dom)" (mouseleave)="updateMouseover('')">
+ (click)="updateOptionsClick(pipelineElement.payload.dom)"
+ (mouseenter)="updateMouseover(pipelineElement.payload.dom)"
+ (mouseleave)="updateMouseover('')"
+ *ngFor="let pipelineElement of rawPipelineModel | enabledPipelineElement">
<span style="z-index:5;"
[ngClass]="getElementCssClasses(pipelineElement)">
<div class="pipeline-element-progress-container sp-fade" *ngIf="pipelineElement.settings.loadingStatus">
@@ -45,4 +47,4 @@
</pipeline-element-options>
</span>
</div>
-</div>
\ No newline at end of file
+
diff --git a/ui/src/app/editor/components/pipeline/pipeline.component.ts b/ui/src/app/editor/components/pipeline/pipeline.component.ts
index dd83082..c5486e7 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.component.ts
+++ b/ui/src/app/editor/components/pipeline/pipeline.component.ts
@@ -23,12 +23,12 @@ import {JsplumbBridge} from "../../services/jsplumb-bridge.service";
import {ShepherdService} from "../../../services/tour/shepherd.service";
import {
ChangeDetectorRef,
- Component,
+ Component, ElementRef,
EventEmitter,
Input,
- NgZone,
+ NgZone, OnDestroy,
OnInit,
- Output
+ Output, ViewChild
} from "@angular/core";
import {
InvocablePipelineElementUnion,
@@ -37,9 +37,9 @@ import {
} from "../../model/editor.model";
import {
CustomOutputStrategy,
- DataProcessorInvocation, ErrorMessage,
- Pipeline,
- SpDataStream
+ DataProcessorInvocation, DataSinkInvocation, ErrorMessage,
+ Pipeline, SpDataSet,
+ SpDataStream, SpDataStreamUnion
} from "../../../core-model/gen/streampipes-model";
import {ObjectProvider} from "../../services/object-provider.service";
import {CustomizeComponent} from "../../dialog/customize/customize.component";
@@ -51,13 +51,17 @@ import {MatchingErrorComponent} from "../../dialog/matching-error/matching-error
import {Tuple2} from "../../../core-model/base/Tuple2";
import {ConfirmDialogComponent} from "../../../core-ui/dialog/confirm-dialog/confirm-dialog.component";
import {MatDialog} from "@angular/material/dialog";
+import {Subject} from "rxjs";
+import {PipelineElementDraggedService} from "../../services/pipeline-element-dragged.service";
+import {PipelineCanvasScrollingService} from "../../services/pipeline-canvas-scrolling.service";
+import {JsplumbFactoryService} from "../../services/jsplumb-factory.service";
@Component({
selector: 'pipeline',
templateUrl: './pipeline.component.html',
styleUrls: ['./pipeline.component.css']
})
-export class PipelineComponent implements OnInit {
+export class PipelineComponent implements OnInit, OnDestroy {
@Input()
pipelineValid: boolean;
@@ -88,25 +92,32 @@ export class PipelineComponent implements OnInit {
availablePipelineElementCache: PipelineElementUnion[];
- plumbReady: any;
+ plumbReady: boolean;
currentMouseOverElement: string;
currentPipelineModel: Pipeline;
idCounter: any;
currentZoomLevel: any;
TransitionService: any;
- // remove later
+ canvasWidth: string = "1000%";
+ canvasHeight: string = "1000%";
+
+ JsplumbBridge: JsplumbBridge;
+
+ //@ViewChild('outerCanvas') canvasRef: ElementRef;
constructor(private JsplumbService: JsplumbService,
private PipelineEditorService: PipelineEditorService,
- private JsplumbBridge: JsplumbBridge,
+ private JsplumbFactoryService: JsplumbFactoryService,
private ObjectProvider: ObjectProvider,
private EditorService: EditorService,
private ShepherdService: ShepherdService,
private PipelineValidationService: PipelineValidationService,
private dialogService: DialogService,
private dialog: MatDialog,
- private ngZone: NgZone) {
+ private ngZone: NgZone,
+ private pipelineElementDraggedService: PipelineElementDraggedService,
+ private pipelineCanvasScrollingService: PipelineCanvasScrollingService) {
this.plumbReady = false;
this.currentMouseOverElement = "";
this.currentPipelineModel = new Pipeline();
@@ -116,21 +127,39 @@ export class PipelineComponent implements OnInit {
}
ngOnInit() {
+ // this.pipelineElementDraggedService.pipelineElementMovedSubject.subscribe(position => {
+ // console.log(position);
+ // console.log(this.canvasHeight);
+ // console.log(this.canvasRef.nativeElement.offsetHeight);
+ // console.log(this.canvasRef.nativeElement.scrollHeight);
+ // if ((position.y + 200) > this.canvasRef.nativeElement.offsetHeight) {
+ // this.canvasHeight = this.canvasRef.nativeElement.offsetHeight +10 + "px";
+ // this.pipelineCanvasScrollingService.canvasScrollYSubject.next(position.y);
+ // }
+ // if ((position.x + 200) > this.canvasRef.nativeElement.offsetWidth) {
+ // this.canvasWidth = this.canvasRef.nativeElement.offsetWidth + 100 + "px";
+ // }
+ // });
+ this.JsplumbBridge = this.JsplumbFactoryService.getJsplumbBridge(this.preview);
this.JsplumbBridge.setContainer(this.canvasId);
this.initAssembly();
this.initPlumb();
}
+ ngAfterViewInit() {
+ }
+
validatePipeline() {
this.ngZone.run(() => {
this.pipelineValid = this.PipelineValidationService
- .isValidPipeline(this.rawPipelineModel.filter(pe => !(pe.settings.disabled)));
+ .isValidPipeline(this.rawPipelineModel.filter(pe => !(pe.settings.disabled)), this.preview);
});
}
ngOnDestroy() {
this.JsplumbBridge.deleteEveryEndpoint();
this.plumbReady = false;
+ //this.pipelineElementDraggedService.pipelineElementMovedSubject.unsubscribe();
}
updateMouseover(elementId) {
@@ -203,18 +232,22 @@ export class PipelineComponent implements OnInit {
this.rawPipelineModel.push(pipelineElementConfig);
if (ui.draggable.hasClass('set')) {
setTimeout(() => {
- this.JsplumbService.setDropped(pipelineElementConfig.payload.dom, pipelineElementConfig.payload, true, false);
+ this.EditorService.updateDataSet(pipelineElementConfig.payload).subscribe(data => {
+ (pipelineElementConfig.payload as SpDataSet).eventGrounding = data.eventGrounding;
+ (pipelineElementConfig.payload as SpDataSet).datasetInvocationId = data.invocationId;
+ this.JsplumbService.dataStreamDropped(pipelineElementConfig.payload.dom, pipelineElementConfig.payload as SpDataSet, true, false);
+ });
}, 0);
}
else if (ui.draggable.hasClass('stream')) {
this.checkTopicModel(pipelineElementConfig);
} else if (ui.draggable.hasClass('sepa')) {
setTimeout(() => {
- this.JsplumbService.sepaDropped(pipelineElementConfig.payload.dom, pipelineElementConfig.payload, true, false);
+ this.JsplumbService.dataProcessorDropped(pipelineElementConfig.payload.dom, pipelineElementConfig.payload as DataProcessorInvocation, true, false);
}, 10);
} else if (ui.draggable.hasClass('action')) {
setTimeout(() => {
- this.JsplumbService.actionDropped(pipelineElementConfig.payload.dom, pipelineElementConfig.payload, true, false);
+ this.JsplumbService.dataSinkDropped(pipelineElementConfig.payload.dom, pipelineElementConfig.payload as DataSinkInvocation, true, false);
}, 10);
}
if (this.ShepherdService.isTourActive()) {
@@ -232,7 +265,10 @@ export class PipelineComponent implements OnInit {
checkTopicModel(pipelineElementConfig: PipelineElementConfig) {
setTimeout(() => {
- this.JsplumbService.streamDropped(pipelineElementConfig.payload.dom, pipelineElementConfig.payload, true, false);
+ this.JsplumbService.dataStreamDropped(pipelineElementConfig.payload.dom,
+ pipelineElementConfig.payload as SpDataStream,
+ true,
+ false);
}, 10);
var streamDescription = pipelineElementConfig.payload as SpDataStream;
@@ -260,7 +296,7 @@ export class PipelineComponent implements OnInit {
initPlumb() {
- this.JsplumbService.prepareJsplumb();
+ //this.JsplumbService.prepareJsplumb();
this.JsplumbBridge.unbind("connection");
@@ -306,8 +342,7 @@ export class PipelineComponent implements OnInit {
info.targetEndpoint.setType("token");
this.validatePipeline();
this.modifyPipeline(pipelineModificationMessage.pipelineModifications);
- var sourceEndpoint = this.JsplumbBridge.selectEndpoints({element: info.targetEndpoint.elementId});
- if (this.PipelineEditorService.isFullyConnected(pe)) {
+ if (this.JsplumbService.isFullyConnected(pe, this.preview)) {
let payload = pe.payload as InvocablePipelineElementUnion;
if ((payload.staticProperties && payload.staticProperties.length > 0) || this.isCustomOutput(pe)) {
this.showCustomizeDialog({a: false, b: pe});
@@ -411,7 +446,9 @@ export class PipelineComponent implements OnInit {
if (c) {
pipelineElementInfo.b.settings.openCustomize = false;
(pipelineElementInfo.b.payload as InvocablePipelineElementUnion).configured = true;
- this.JsplumbService.activateEndpoint(pipelineElementInfo.b.payload.dom, pipelineElementInfo.b.settings.completed);
+ if (!(pipelineElementInfo.b.payload instanceof DataSinkInvocation)) {
+ this.JsplumbBridge.activateEndpoint("out-" + pipelineElementInfo.b.payload.dom, pipelineElementInfo.b.settings.completed);
+ }
this.JsplumbBridge.getSourceEndpoint(pipelineElementInfo.b.payload.dom).setType("token");
this.triggerPipelineCacheUpdate();
this.announceConfiguredElement(pipelineElementInfo.b);
@@ -425,4 +462,4 @@ export class PipelineComponent implements OnInit {
}
-}
\ No newline at end of file
+}
diff --git a/ui/src/app/editor/editor.module.ts b/ui/src/app/editor/editor.module.ts
index 511678d..1794b56 100644
--- a/ui/src/app/editor/editor.module.ts
+++ b/ui/src/app/editor/editor.module.ts
@@ -60,6 +60,12 @@ import {PropertySelectionComponent} from "./components/output-strategy/property-
import {UserDefinedOutputStrategyComponent} from "./components/output-strategy/user-defined-output/user-defined-output.component";
import {ConnectModule} from "../connect/connect.module";
import {PipelineElementTemplateConfigComponent} from "./components/pipeline-element-template-config/pipeline-element-template-config.component";
+import {EnabledPipelineElementFilter} from "./filter/enabled-pipeline-element.filter";
+import {PipelineElementDraggedService} from "./services/pipeline-element-dragged.service";
+import {PipelineCanvasScrollingService} from "./services/pipeline-canvas-scrolling.service";
+import {PerfectScrollbarModule} from "ngx-perfect-scrollbar";
+import {JsplumbEndpointService} from "./services/jsplumb-endpoint.service";
+import {JsplumbFactoryService} from "./services/jsplumb-factory.service";
@NgModule({
imports: [
@@ -76,13 +82,15 @@ import {PipelineElementTemplateConfigComponent} from "./components/pipeline-elem
FormsModule,
MatProgressSpinnerModule,
ShowdownModule,
- ReactiveFormsModule
+ ReactiveFormsModule,
+ PerfectScrollbarModule
],
declarations: [
CompatibleElementsComponent,
CustomizeComponent,
CustomOutputStrategyComponent,
EditorComponent,
+ EnabledPipelineElementFilter,
HelpComponent,
MatchingErrorComponent,
MissingElementsForTutorialComponent,
@@ -104,16 +112,19 @@ import {PipelineElementTemplateConfigComponent} from "./components/pipeline-elem
providers: [
EditorService,
SemanticTypeUtilsService,
- JsplumbBridge,
+ JsplumbFactoryService,
+ JsplumbEndpointService,
JsplumbService,
JsplumbConfigService,
ObjectProvider,
+ PipelineCanvasScrollingService,
+ PipelineElementDraggedService,
PipelineEditorService,
PipelinePositioningService,
PipelineValidationService,
PipelineElementRecommendationService,
ImageChecker,
- SafeCss
+ SafeCss,
],
exports: [
EditorComponent,
diff --git a/ui/src/app/editor/filter/enabled-pipeline-element.filter.ts b/ui/src/app/editor/filter/enabled-pipeline-element.filter.ts
new file mode 100644
index 0000000..8abb26d
--- /dev/null
+++ b/ui/src/app/editor/filter/enabled-pipeline-element.filter.ts
@@ -0,0 +1,15 @@
+import {Pipe, PipeTransform} from "@angular/core";
+import {PipelineElementConfig} from "../model/editor.model";
+
+@Pipe({
+ name: 'enabledPipelineElement',
+ pure: false
+})
+export class EnabledPipelineElementFilter implements PipeTransform {
+ transform(items: PipelineElementConfig[]): any {
+ if (!items) {
+ return items;
+ }
+ return items.filter(item => item.settings.disabled == undefined || !item.settings.disabled);
+ }
+}
diff --git a/ui/src/app/editor/model/editor.model.ts b/ui/src/app/editor/model/editor.model.ts
index 692d7c3..ab103db 100644
--- a/ui/src/app/editor/model/editor.model.ts
+++ b/ui/src/app/editor/model/editor.model.ts
@@ -29,6 +29,11 @@ export type PipelineElementHolder = {
[key: string]: Array<PipelineElementUnion>;
};
+export interface PipelineElementPosition {
+ x: number;
+ y: number;
+}
+
export interface PipelineElementConfig {
type: string,
settings: {
@@ -80,4 +85,4 @@ export const PIPELINE_ELEMENT_TOKEN = new InjectionToken<{}>('pipelineElement');
export type PipelineElementIdentifier = "org.apache.streampipes.model.SpDataStream"
| "org.apache.streampipes.model.SpDataSet"
| "org.apache.streampipes.model.graph.DataProcessorInvocation"
- | "org.apache.streampipes.model.graph.DataSinkInvocation";
\ No newline at end of file
+ | "org.apache.streampipes.model.graph.DataSinkInvocation";
diff --git a/ui/src/app/editor/model/jsplumb.model.ts b/ui/src/app/editor/model/jsplumb.model.ts
new file mode 100644
index 0000000..3d9dddc
--- /dev/null
+++ b/ui/src/app/editor/model/jsplumb.model.ts
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ *
+ */
+
+export interface JsplumbSettings {
+ dotRadius: number,
+ lineWidth: number,
+ arrowWidth: number,
+ arrowLength: number,
+ arrowLineWidth: number,
+ curviness: number
+}
diff --git a/ui/src/app/editor/services/jsplumb-bridge.service.ts b/ui/src/app/editor/services/jsplumb-bridge.service.ts
index 82631d1..ca94753 100644
--- a/ui/src/app/editor/services/jsplumb-bridge.service.ts
+++ b/ui/src/app/editor/services/jsplumb-bridge.service.ts
@@ -16,107 +16,130 @@
*
*/
-import {Injectable} from "@angular/core";
+import {jsPlumbInstance} from 'jsplumb'
-declare const jsPlumb: any;
-
-@Injectable()
export class JsplumbBridge {
- constructor() {
+ constructor(private jsPlumbInstance: jsPlumbInstance) {
+ }
+
+ activateEndpoint(endpointId: string, endpointEnabled: boolean) {
+ let endpoint = this.getEndpointById(endpointId);
+ endpoint.setEnabled(endpointEnabled);
+ }
+
+ activateEndpointWithType(endpointId: string, endpointEnabled: boolean, endpointType: string) {
+ this.activateEndpoint(endpointId, endpointEnabled);
+ this.setEndpointType(endpointId, endpointType);
+ }
+
+ setEndpointType(endpointId: string, endpointType: string) {
+ let endpoint = this.getEndpointById(endpointId);
+ // @ts-ignore
+ endpoint.setType(endpointType);
+ }
+
+ getEndpointById(endpointId: string) {
+ return this.jsPlumbInstance.getEndpoint(endpointId);
}
setZoom(scale) {
- jsPlumb.setZoom(scale);
+ this.jsPlumbInstance.setZoom(scale);
}
repaintEverything() {
- jsPlumb.repaintEverything(true);
+ this.jsPlumbInstance.repaintEverything(true);
}
deleteEveryEndpoint() {
- jsPlumb.deleteEveryEndpoint();
+ this.jsPlumbInstance.deleteEveryEndpoint();
}
setContainer(container) {
- jsPlumb.setContainer(container);
+ this.jsPlumbInstance.setContainer(container);
}
unbind(element) {
- jsPlumb.unbind(element);
+ this.jsPlumbInstance.unbind(element);
}
bind(event, fn) {
- return jsPlumb.bind(event, fn);
+ return this.jsPlumbInstance.bind(event, fn);
}
// TODO: Overloading Functions?
selectEndpoints(endpoint?) {
if (endpoint === undefined) {
- return jsPlumb.selectEndpoints();
+ // @ts-ignore
+ return this.jsPlumbInstance.selectEndpoints();
}
- return jsPlumb.selectEndpoints(endpoint);
+ // @ts-ignore
+ return this.jsPlumbInstance.selectEndpoints(endpoint);
}
selectEndpointsById(id) {
- return jsPlumb.selectEndpoints({source: id});
+ // @ts-ignore
+ return this.jsPlumbInstance.selectEndpoints({source: id});
}
getSourceEndpoint(id) {
- return jsPlumb.selectEndpoints({source: id});
+ // @ts-ignore
+ return this.jsPlumbInstance.selectEndpoints({source: id});
}
getTargetEndpoint(id) {
- return jsPlumb.selectEndpoints({target: id});
+ // @ts-ignore
+ return this.jsPlumbInstance.selectEndpoints({target: id});
}
getEndpointCount(id) {
- return jsPlumb.selectEndpoints({element: id}).length;
+ // @ts-ignore
+ return this.jsPlumbInstance.selectEndpoints({element: id}).length;
}
detach(connection) {
- jsPlumb.detach(connection);
+ this.jsPlumbInstance.deleteConnection(connection);
}
getConnections(filter) {
- return jsPlumb.getConnections(filter);
+ return this.jsPlumbInstance.getConnections(filter, {});
}
addEndpoint(element, options) {
- return jsPlumb.addEndpoint(element, options);
+ return this.jsPlumbInstance.addEndpoint(element, options);
}
connect(connection) {
- jsPlumb.connect(connection);
+ this.jsPlumbInstance.connect(connection);
}
removeAllEndpoints(element) {
- jsPlumb.removeAllEndpoints(element);
+ this.jsPlumbInstance.removeAllEndpoints(element);
}
registerEndpointTypes(typeInfo) {
- jsPlumb.registerEndpointTypes(typeInfo);
+ this.jsPlumbInstance.registerEndpointTypes(typeInfo);
}
draggable(element, option) {
- jsPlumb.draggable(element, option);
+ this.jsPlumbInstance.draggable(element, option);
}
// TODO: Overloading Functions?
setSuspendDrawing(bool1, bool2?) {
if (bool2 === undefined) {
- jsPlumb.setSuspendDrawing(bool1);
+ this.jsPlumbInstance.setSuspendDrawing(bool1);
} else {
- jsPlumb.setSuspendDrawing(bool1, bool2);
+ this.jsPlumbInstance.setSuspendDrawing(bool1, bool2);
}
}
getAllConnections() {
- return jsPlumb.getAllConnections();
+ return this.jsPlumbInstance.getAllConnections();
}
reset() {
- jsPlumb.reset();
+ this.jsPlumbInstance.reset();
}
}
diff --git a/ui/src/app/editor/services/jsplumb-config.service.ts b/ui/src/app/editor/services/jsplumb-config.service.ts
index c18d55b..44de61c 100644
--- a/ui/src/app/editor/services/jsplumb-config.service.ts
+++ b/ui/src/app/editor/services/jsplumb-config.service.ts
@@ -17,6 +17,7 @@
*/
import {Injectable} from "@angular/core";
+import {JsplumbSettings} from "../model/jsplumb.model";
@Injectable()
export class JsplumbConfigService {
@@ -33,28 +34,33 @@ export class JsplumbConfigService {
}
makeConfig(settings) {
- let config = {};
- config['streamEndpointOptions'] = this.makeStreamEndpointOptions(settings);
- config['sepaEndpointOptions'] = this.makeSepaEndpointOptions(settings);
- config['leftTargetPointOptions'] = this.makeLeftTargetPointOptions(settings);
+ let config = {} as any;
+ config.streamEndpointOptions = this.makeStreamEndpointOptions(settings);
+ config.sepaEndpointOptions = this.makeSepaEndpointOptions(settings);
+ config.leftTargetPointOptions = this.makeLeftTargetPointOptions(settings);
return config;
}
- makeSettings(dotRadius, lineWidth, arrowWidth, arrowLength, arrowLineWidth, curviness) {
- let settings = {};
- settings['dotRadius'] = dotRadius;
- settings['lineWidth'] = lineWidth;
- settings['arrowWidth'] = arrowWidth;
- settings['arrowLength'] = arrowLength;
- settings['arrowLineWidth'] = arrowLineWidth;
- settings['curviness'] = curviness;
+ makeSettings(dotRadius: number,
+ lineWidth: number,
+ arrowWidth: number,
+ arrowLength: number,
+ arrowLineWidth: number,
+ curviness: number) {
+ let settings = {} as JsplumbSettings;
+ settings.dotRadius = dotRadius;
+ settings.lineWidth = lineWidth;
+ settings.arrowWidth = arrowWidth;
+ settings.arrowLength = arrowLength;
+ settings.arrowLineWidth = arrowLineWidth;
+ settings.curviness = curviness;
return settings;
}
- makeStreamEndpointOptions(settings) {
+ makeStreamEndpointOptions(settings: JsplumbSettings) {
return {
endpoint: ["Dot", {radius: settings.dotRadius}],
- connectorStyle: {strokeStyle: "#BDBDBD", outlineColor: "#9E9E9E", lineWidth: settings.lineWidth},
+ connectorStyle: {stroke: "#BDBDBD", outlineStroke: "#BDBDBD", strokeWidth: settings.lineWidth},
connector: ["Bezier", {curviness: settings.curviness}],
isSource: true,
maxConnections: -1,
@@ -64,8 +70,8 @@ export class JsplumbConfigService {
["Arrow", {
width: settings.arrowWidth, length: settings.arrowLength, location: 0.5, id: "arrow", paintStyle: {
fillStyle: "#BDBDBD",
- strokeStyle: "#9E9E9E",
- lineWidth: settings.arrowLineWidth
+ stroke: "#9E9E9E",
+ strokeWidth: settings.arrowLineWidth
}
}],
]
@@ -76,7 +82,7 @@ export class JsplumbConfigService {
return {
endpoint: ["Dot", {radius: settings.dotRadius}],
connectorStyle: {
- strokeStyle: "#BDBDBD", outlineColor: "#9E9E9E", lineWidth: settings.lineWidth
+ stroke: "#BDBDBD", outlineStroke: "#9E9E9E", strokeWidth: settings.lineWidth
},
connector: ["Bezier", {curviness: settings.curviness}],
isSource: true,
@@ -86,9 +92,9 @@ export class JsplumbConfigService {
connectorOverlays: [
["Arrow", {
width: settings.arrowWidth, length: settings.arrowLength, location: 0.5, id: "arrow", paintStyle: {
- fillStyle: "#BDBDBD",
- strokeStyle: "#9E9E9E",
- lineWidth: settings.arrowLineWidth
+ fill: "#BDBDBD",
+ stroke: "#9E9E9E",
+ strokeWidth: settings.arrowLineWidth
}
}],
],
@@ -108,5 +114,3 @@ export class JsplumbConfigService {
}
}
-
-//JsplumbConfigService.$inject = [];
\ No newline at end of file
diff --git a/ui/src/app/editor/services/jsplumb-endpoint.service.ts b/ui/src/app/editor/services/jsplumb-endpoint.service.ts
new file mode 100644
index 0000000..e3e7be3
--- /dev/null
+++ b/ui/src/app/editor/services/jsplumb-endpoint.service.ts
@@ -0,0 +1,63 @@
+/*
+ * 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 {Injectable} from "@angular/core";
+import {JsplumbConfigService} from "./jsplumb-config.service";
+
+@Injectable()
+export class JsplumbEndpointService {
+
+ constructor(private jsplumbConfigService: JsplumbConfigService) {
+
+ }
+
+ getJsplumbConfig(preview): any {
+ return preview ? this.jsplumbConfigService.getPreviewConfig() : this.jsplumbConfigService.getEditorConfig();
+ }
+
+ getStreamEndpoint(preview: boolean,
+ pipelineElementDomId: string) {
+ let jsplumbConfig = this.getJsplumbConfig(preview);
+ let config = jsplumbConfig.streamEndpointOptions;
+ config.uuid = "out-" + pipelineElementDomId;
+ return config;
+ }
+
+ getInputEndpoint(preview, pipelineElementDomId, index): any {
+ let jsplumbConfig = this.getJsplumbConfig(preview);
+ let inConfig = jsplumbConfig.leftTargetPointOptions;
+ inConfig.uuid = "in-" + index + "-" + pipelineElementDomId;
+ return inConfig;
+ }
+
+ getOutputEndpoint(preview, pipelineElementDomId): any {
+ let jsplumbConfig = this.getJsplumbConfig(preview);
+ let outConfig = jsplumbConfig.sepaEndpointOptions;
+ outConfig.uuid = "out-" + pipelineElementDomId;
+ return outConfig;
+ }
+
+ getNewTargetPoint(preview, x, y, pipelineElementDomId, index): any {
+ let inConfig = this.getInputEndpoint(preview, pipelineElementDomId, index);
+ inConfig.type = "empty";
+ inConfig.anchor = [x, y, -1, 0];
+ inConfig.isTarget = true;
+
+ return inConfig;
+ }
+}
diff --git a/ui/src/app/editor/services/jsplumb-factory.service.ts b/ui/src/app/editor/services/jsplumb-factory.service.ts
new file mode 100644
index 0000000..ff16482
--- /dev/null
+++ b/ui/src/app/editor/services/jsplumb-factory.service.ts
@@ -0,0 +1,85 @@
+/*
+ * 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 {jsPlumb, jsPlumbInstance} from "jsplumb";
+import {JsplumbBridge} from "./jsplumb-bridge.service";
+import {Injectable} from "@angular/core";
+
+@Injectable()
+export class JsplumbFactoryService {
+
+ pipelineEditorInstance: jsPlumbInstance;
+ pipelinePreviewInstance: jsPlumbInstance;
+
+ pipelineEditorBridge: JsplumbBridge;
+ pipelinePreviewBridge: JsplumbBridge;
+
+ constructor() {
+ this.pipelineEditorInstance = this.makePipelineEditorInstance();
+ this.pipelinePreviewInstance = this.makePipelinePreviewInstance();
+
+ this.pipelineEditorBridge = new JsplumbBridge(this.pipelineEditorInstance);
+ this.pipelinePreviewBridge = new JsplumbBridge(this.pipelinePreviewInstance);
+
+ this.prepareJsplumb(this.pipelineEditorInstance);
+ this.prepareJsplumb(this.pipelinePreviewInstance);
+ }
+
+ getJsplumbBridge(previewConfig: boolean): JsplumbBridge {
+ return previewConfig ? this.pipelineEditorBridge : this.pipelinePreviewBridge;
+ }
+
+ makePipelineEditorInstance(): jsPlumbInstance {
+ return jsPlumb.getInstance();
+ }
+
+ makePipelinePreviewInstance(): jsPlumbInstance {
+ return jsPlumb.getInstance();
+ }
+
+ prepareJsplumb(jsplumbInstance: jsPlumbInstance) {
+ jsplumbInstance.registerEndpointTypes({
+ "empty": {
+ paintStyle: {
+ fill: "white",
+ stroke: "#9E9E9E",
+ strokeWidth: 2,
+ }
+ },
+ "token": {
+ paintStyle: {
+ fill: "#BDBDBD",
+ stroke: "#9E9E9E",
+ strokeWidth: 2
+ },
+ hoverPaintStyle: {
+ fill: "#BDBDBD",
+ stroke: "#4CAF50",
+ strokeWidth: 4,
+ }
+ },
+ "highlight": {
+ paintStyle: {
+ fill: "white",
+ stroke: "#4CAF50",
+ strokeWidth: 4
+ }
+ }
+ });
+ }
+}
diff --git a/ui/src/app/editor/services/jsplumb.service.ts b/ui/src/app/editor/services/jsplumb.service.ts
index 96190da..4196480 100644
--- a/ui/src/app/editor/services/jsplumb.service.ts
+++ b/ui/src/app/editor/services/jsplumb.service.ts
@@ -19,63 +19,45 @@
import {JsplumbConfigService} from "./jsplumb-config.service";
import {JsplumbBridge} from "./jsplumb-bridge.service";
import {Injectable} from "@angular/core";
-import {PipelineElementConfig, PipelineElementUnion} from "../model/editor.model";
+import {
+ InvocablePipelineElementUnion,
+ PipelineElementConfig,
+ PipelineElementUnion
+} from "../model/editor.model";
import {PipelineElementTypeUtils} from "../utils/editor.utils";
import {
DataProcessorInvocation,
DataSinkInvocation,
+ Pipeline,
SpDataSet,
- SpDataStream
+ SpDataStream,
+ SpDataStreamUnion
} from "../../core-model/gen/streampipes-model";
-import {EditorService} from "./editor.service";
+import {PipelineElementDraggedService} from "./pipeline-element-dragged.service";
+import {JsplumbEndpointService} from "./jsplumb-endpoint.service";
+import {JsplumbFactoryService} from "./jsplumb-factory.service";
@Injectable()
export class JsplumbService {
- idCounter: any;
+ idCounter: number = 0;
constructor(private JsplumbConfigService: JsplumbConfigService,
- private JsplumbBridge: JsplumbBridge,
- private EditorService: EditorService) {
- this.idCounter = 0;
- }
-
- prepareJsplumb() {
- this.JsplumbBridge.registerEndpointTypes({
- "empty": {
- paintStyle: {
- fillStyle: "white",
- strokeStyle: "#9E9E9E",
- lineWidth: 2
- }
- },
- "token": {
- paintStyle: {
- fillStyle: "#BDBDBD",
- strokeStyle: "#9E9E9E",
- lineWidth: 2
- },
- hoverPaintStyle: {
- fillStyle: "#BDBDBD",
- strokeStyle: "#4CAF50",
- lineWidth: 4
- }
- },
- "highlight": {
- paintStyle: {
- fillStyle: "white",
- strokeStyle: "#4CAF50",
- lineWidth: 4
- }
- }
- });
+ private JsplumbFactory: JsplumbFactoryService,
+ private jsplumbEndpointService: JsplumbEndpointService,
+ private pipelineElementDraggedService: PipelineElementDraggedService) {
}
- activateEndpoint(endpointId, endpointEnabled) {
- this.JsplumbBridge.selectEndpointsById(endpointId).setEnabled(endpointEnabled);
+ isFullyConnected(pipelineElementConfig: PipelineElementConfig,
+ previewConfig: boolean) {
+ let jsplumbBridge = this.JsplumbFactory.getJsplumbBridge(previewConfig);
+ let payload = pipelineElementConfig.payload as InvocablePipelineElementUnion;
+ return payload.inputStreams == null ||
+ jsplumbBridge.getConnections({target: $("#" +payload.dom)}).length == payload.inputStreams.length;
}
- makeRawPipeline(pipelineModel, isPreview) {
+ makeRawPipeline(pipelineModel: Pipeline,
+ isPreview: boolean) {
return pipelineModel
.streams
.map(s => this.toConfig(s, "stream", isPreview))
@@ -83,59 +65,69 @@ export class JsplumbService {
.concat(pipelineModel.actions.map(s => this.toConfig(s, "action", isPreview)));
}
- toConfig(pe, type, isPreview) {
- pe.type = type;
+ toConfig(pe: PipelineElementUnion,
+ type: string,
+ isPreview: boolean) {
+ (pe as any).type = type;
return this.createNewPipelineElementConfig(pe, {x: 100, y: 100}, isPreview, true);
}
-
- createElement(pipelineModel, pipelineElement, pipelineElementDomId) {
+ createElement(pipelineModel: PipelineElementConfig[],
+ pipelineElement: InvocablePipelineElementUnion,
+ pipelineElementDomId: string) {
var pipelineElementDom = $("#" + pipelineElementDomId);
var pipelineElementConfig = this.createNewPipelineElementConfigWithFixedCoordinates(pipelineElementDom, pipelineElement, false);
pipelineModel.push(pipelineElementConfig);
setTimeout(() => {
- this.createAssemblyElement(pipelineElementConfig.payload.dom, pipelineElementConfig.payload, pipelineElementDom);
+ this.createAssemblyElement(pipelineElementConfig.payload.dom,
+ pipelineElementConfig.payload as InvocablePipelineElementUnion,
+ pipelineElementDom,
+ false);
});
}
- createAssemblyElement($newElementId, json, $parentElement) {
+ createAssemblyElement(pipelineElementDomId: string,
+ pipelineElement: InvocablePipelineElementUnion,
+ $parentElement,
+ previewConfig: boolean) {
var $target;
- if (json.belongsTo.indexOf("sepa") > 0) { //Sepa Element
- $target = this.sepaDropped($newElementId, json, true, false);
- this.connectNodes($parentElement, $target);
+ if (pipelineElement.belongsTo.indexOf("sepa") > 0) { //Sepa Element
+ $target = this.dataProcessorDropped(pipelineElementDomId, pipelineElement as DataProcessorInvocation, true, false);
+ this.connectNodes($parentElement, $target, previewConfig);
} else {
- $target = this.actionDropped($newElementId, json, true, false);
- this.connectNodes($parentElement, $target);
+ $target = this.dataSinkDropped(pipelineElementDomId, pipelineElement, true, false);
+ this.connectNodes($parentElement, $target, previewConfig);
}
}
- connectNodes($parentElement, $target) {
+ connectNodes($parentElement, $target, previewConfig: boolean) {
var options;
+ let jsplumbBridge = this.getBridge(previewConfig);
if ($parentElement.hasClass("stream")) {
// TODO: getJsplumbConfig depends on isPreview. Not implemented yet
- options = this.getJsplumbConfig(true).streamEndpointOptions;
+ options = this.jsplumbEndpointService.getJsplumbConfig(true).streamEndpointOptions;
} else {
// TODO: getJsplumbConfig depends on isPreview. Not implemented yet
- options = this.getJsplumbConfig(true).sepaEndpointOptions;
+ options = this.jsplumbEndpointService.getJsplumbConfig(true).sepaEndpointOptions;
}
var sourceEndPoint;
- if (this.JsplumbBridge.selectEndpoints({source: $parentElement}).length > 0) {
- if (!(this.JsplumbBridge.selectEndpoints({source: $parentElement}).get(0).isFull())) {
- sourceEndPoint = this.JsplumbBridge.selectEndpoints({source: $parentElement}).get(0)
+ if (jsplumbBridge.selectEndpoints({source: $parentElement}).length > 0) {
+ if (!(jsplumbBridge.selectEndpoints({source: $parentElement}).get(0).isFull())) {
+ sourceEndPoint = jsplumbBridge.selectEndpoints({source: $parentElement}).get(0)
} else {
- sourceEndPoint = this.JsplumbBridge.addEndpoint($parentElement, options);
+ sourceEndPoint = jsplumbBridge.addEndpoint($parentElement, options);
}
} else {
- sourceEndPoint = this.JsplumbBridge.addEndpoint($parentElement, options);
+ sourceEndPoint = jsplumbBridge.addEndpoint($parentElement, options);
}
- var targetEndPoint = this.JsplumbBridge.selectEndpoints({target: $target}).get(0);
+ var targetEndPoint = jsplumbBridge.selectEndpoints({target: $target}).get(0);
- this.JsplumbBridge.connect({source: sourceEndPoint, target: targetEndPoint, detachable: true});
- this.JsplumbBridge.repaintEverything();
+ jsplumbBridge.connect({source: sourceEndPoint, target: targetEndPoint, detachable: true});
+ jsplumbBridge.repaintEverything();
}
- createNewPipelineElementConfigWithFixedCoordinates($parentElement, json, isPreview) {
+ createNewPipelineElementConfigWithFixedCoordinates($parentElement, json, isPreview): PipelineElementConfig {
var x = $parentElement.position().left;
var y = $parentElement.position().top;
var coord = {'x': x + 200, 'y': y};
@@ -183,7 +175,7 @@ export class JsplumbService {
}
}
- makeId(count) {
+ makeId(count: number) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@@ -193,82 +185,64 @@ export class JsplumbService {
return text;
}
- streamDropped(pipelineElementDomId, json, endpoints, preview) {
+ dataStreamDropped(pipelineElementDomId: string,
+ pipelineElement: SpDataStreamUnion,
+ endpoints: boolean,
+ preview: boolean) {
+ let jsplumbBridge = this.getBridge(preview);
if (endpoints) {
if (!preview) {
- this.JsplumbBridge.draggable(pipelineElementDomId, {containment: 'parent'});
+ jsplumbBridge.draggable(pipelineElementDomId, {containment: 'parent',
+ // drag: (e => {
+ // this.pipelineElementDraggedService.notify({x: e.pos[0], y: e.pos[1]});
+ // })
+ });
}
- this.JsplumbBridge.addEndpoint(pipelineElementDomId, this.getStreamEndpoint(preview, pipelineElementDomId));
+ let endpointOptions = this.jsplumbEndpointService.getStreamEndpoint(preview, pipelineElementDomId);
+ jsplumbBridge.addEndpoint(pipelineElementDomId, endpointOptions);
}
return pipelineElementDomId;
};
- setDropped($newElement, json, endpoints, preview) {
- this.EditorService.updateDataSet(json).subscribe(data => {
- json.eventGrounding = data.eventGrounding;
- json.datasetInvocationId = data.invocationId;
- this.streamDropped($newElement, json, endpoints, preview);
- });
- }
-
- sepaDropped(pipelineElementDomId, json, endpoints, preview) {
- this.actionDropped(pipelineElementDomId, json, endpoints, preview);
+ dataProcessorDropped(pipelineElementDomId: string,
+ pipelineElement: DataProcessorInvocation,
+ endpoints: boolean,
+ preview: boolean): string {
+ let jsplumbBridge = this.getBridge(preview);
+ this.dataSinkDropped(pipelineElementDomId, pipelineElement, endpoints, preview);
if (endpoints) {
- this.JsplumbBridge.addEndpoint(pipelineElementDomId, this.getOutputEndpoint(preview, pipelineElementDomId));
+ jsplumbBridge.addEndpoint(pipelineElementDomId,
+ this.jsplumbEndpointService.getOutputEndpoint(preview, pipelineElementDomId));
}
return pipelineElementDomId;
};
- actionDropped(pipelineElementDomId, json, endpoints, preview) {
+ dataSinkDropped(pipelineElementDomId: string,
+ pipelineElement: InvocablePipelineElementUnion,
+ endpoints: boolean,
+ preview: boolean): string {
+ let jsplumbBridge = this.getBridge(preview);
if (!preview) {
- this.JsplumbBridge.draggable(pipelineElementDomId, {containment: 'parent'});
+ jsplumbBridge.draggable(pipelineElementDomId, {containment: 'parent'});
}
if (endpoints) {
- if (json.inputStreams.length < 2) { //1 InputNode
- this.JsplumbBridge.addEndpoint(pipelineElementDomId, this.getInputEndpoint(preview, pipelineElementDomId, 0));
+ if (pipelineElement.inputStreams.length < 2) { //1 InputNode
+ jsplumbBridge.addEndpoint(pipelineElementDomId,
+ this.jsplumbEndpointService.getInputEndpoint(preview, pipelineElementDomId, 0));
} else {
- this.JsplumbBridge.addEndpoint(pipelineElementDomId, this.getNewTargetPoint(preview, 0, 0.25, pipelineElementDomId, 0));
- this.JsplumbBridge.addEndpoint(pipelineElementDomId, this.getNewTargetPoint(preview, 0, 0.75, pipelineElementDomId, 1));
+ jsplumbBridge.addEndpoint(pipelineElementDomId,
+ this.jsplumbEndpointService.getNewTargetPoint(preview, 0, 0.25, pipelineElementDomId, 0));
+ jsplumbBridge.addEndpoint(pipelineElementDomId,
+ this.jsplumbEndpointService.getNewTargetPoint(preview, 0, 0.75, pipelineElementDomId, 1));
}
}
return pipelineElementDomId;
};
- getJsplumbConfig(preview): any {
- return preview ? this.JsplumbConfigService.getPreviewConfig() : this.JsplumbConfigService.getEditorConfig();
+ getBridge(previewConfig: boolean): JsplumbBridge {
+ return this.JsplumbFactory.getJsplumbBridge(previewConfig);
}
- getStreamEndpoint(preview, pipelineElementDomId) {
- var jsplumbConfig = this.getJsplumbConfig(preview);
- let config = jsplumbConfig.streamEndpointOptions;
- config.uuid = "out-" + pipelineElementDomId;
- return config;
- }
-
- getInputEndpoint(preview, pipelineElementDomId, index): any {
- var jsplumbConfig = this.getJsplumbConfig(preview);
- let inConfig = jsplumbConfig.leftTargetPointOptions;
- inConfig.uuid = "in-" + index + "-" + pipelineElementDomId;
- return inConfig;
- }
-
- getOutputEndpoint(preview, pipelineElementDomId): any {
- var jsplumbConfig = this.getJsplumbConfig(preview);
- let outConfig = jsplumbConfig.sepaEndpointOptions;
- outConfig.uuid = "out-" + pipelineElementDomId;
- return outConfig;
- }
-
- getNewTargetPoint(preview, x, y, pipelineElementDomId, index): any {
- let inConfig = this.getInputEndpoint(preview, pipelineElementDomId, index);
- inConfig.type = "empty";
- inConfig.anchor = [x, y, -1, 0];
- inConfig.isTarget = true;
-
- return inConfig;
- }
}
-
-//JsplumbService.$inject = ['JsplumbConfigService', 'JsplumbBridge', '$timeout', 'RestApi'];
diff --git a/ui/src/app/editor/services/object-provider.service.ts b/ui/src/app/editor/services/object-provider.service.ts
index 1562e55..5e951c7 100644
--- a/ui/src/app/editor/services/object-provider.service.ts
+++ b/ui/src/app/editor/services/object-provider.service.ts
@@ -18,17 +18,17 @@
import {Injectable} from "@angular/core";
import {RestApi} from "../../services/rest-api.service";
-import {JsplumbBridge} from "./jsplumb-bridge.service";
import {InvocablePipelineElementUnion, PipelineElementConfig} from "../model/editor.model";
-import {Pipeline} from "../../core-model/gen/streampipes-model";
+import {DataSinkInvocation, Pipeline} from "../../core-model/gen/streampipes-model";
import {EditorService} from "./editor.service";
+import {JsplumbFactoryService} from "./jsplumb-factory.service";
@Injectable()
export class ObjectProvider {
constructor(private RestApi: RestApi,
- private JsplumbBridge: JsplumbBridge,
- private EditorService: EditorService) {
+ private EditorService: EditorService,
+ private JsplumbFactoryService: JsplumbFactoryService) {
}
prepareElement(pipelineElement: InvocablePipelineElementUnion) {
@@ -57,6 +57,19 @@ export class ObjectProvider {
return pipeline;
}
+ hasConnectedPipelineElement(pipelineElementDomId: string,
+ rawPipelineModel: PipelineElementConfig[]) {
+ let pipelineElement = this.findElement(pipelineElementDomId, rawPipelineModel);
+ if (pipelineElement.payload instanceof DataSinkInvocation) {
+ return false;
+ } else {
+ return rawPipelineModel
+ .filter(pe => !pe.settings.disabled && pe.payload.connectedTo)
+ .find(pe => (pe.payload.connectedTo.indexOf(pipelineElementDomId) > -1))
+ != undefined;
+ }
+ }
+
findElement(elementId, rawPipelineModel: PipelineElementConfig[]): PipelineElementConfig {
let result = {} as PipelineElementConfig;
rawPipelineModel.forEach(pe => {
@@ -68,12 +81,13 @@ export class ObjectProvider {
}
addElementNew(pipeline, currentPipelineElements: PipelineElementConfig[]): Pipeline {
+ let JsplumbBridge = this.JsplumbFactoryService.getJsplumbBridge(false);
currentPipelineElements.forEach(pe => {
if (pe.settings.disabled == undefined || !(pe.settings.disabled)) {
if (pe.type === 'sepa' || pe.type === 'action') {
let payload = pe.payload;
payload = this.prepareElement(payload as InvocablePipelineElementUnion);
- let connections = this.JsplumbBridge.getConnections({
+ let connections = JsplumbBridge.getConnections({
target: $("#" + payload.dom)
});
for (let i = 0; i < connections.length; i++) {
diff --git a/ui/src/app/editor/services/pipeline-canvas-scrolling.service.ts b/ui/src/app/editor/services/pipeline-canvas-scrolling.service.ts
new file mode 100644
index 0000000..4eef96e
--- /dev/null
+++ b/ui/src/app/editor/services/pipeline-canvas-scrolling.service.ts
@@ -0,0 +1,35 @@
+/*
+ * 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 {Injectable} from "@angular/core";
+import {Subject} from "rxjs";
+
+@Injectable()
+export class PipelineCanvasScrollingService {
+
+ public canvasScrollXSubject: Subject<number> = new Subject<number>();
+ public canvasScrollYSubject: Subject<number> = new Subject<number>();
+
+ public notifyX(position: number): void {
+ this.canvasScrollXSubject.next(position);
+ }
+
+ public notifyY(position: number): void {
+ this.canvasScrollYSubject.next(position);
+ }
+}
diff --git a/ui/src/app/editor/services/pipeline-editor.service.ts b/ui/src/app/editor/services/pipeline-editor.service.ts
index c630e14..fea88eb 100644
--- a/ui/src/app/editor/services/pipeline-editor.service.ts
+++ b/ui/src/app/editor/services/pipeline-editor.service.ts
@@ -17,13 +17,11 @@
*/
import {Injectable} from "@angular/core";
-import {JsplumbBridge} from "./jsplumb-bridge.service";
-import {InvocablePipelineElementUnion, PipelineElementConfig} from "../model/editor.model";
@Injectable()
export class PipelineEditorService {
- constructor(private JsplumbBridge: JsplumbBridge) {
+ constructor() {
}
getCoordinates(ui, currentZoomLevel) {
@@ -36,19 +34,6 @@ export class PipelineEditorService {
};
}
- isConnected(element) {
- if (this.JsplumbBridge.getConnections({source: element}).length < 1 && this.JsplumbBridge.getConnections({target: element}).length < 1) {
- return false;
- }
- return true;
- }
-
- isFullyConnected(pipelineElementConfig: PipelineElementConfig) {
- let payload = pipelineElementConfig.payload as InvocablePipelineElementUnion;
- return payload.inputStreams == null ||
- this.JsplumbBridge.getConnections({target: $("#" +payload.dom)}).length == payload.inputStreams.length;
- }
-
getDropPositionY(helper, currentZoomLevel) {
var newTop;
var helperPos = helper.offset();
@@ -66,5 +51,3 @@ export class PipelineEditorService {
}
}
-
-//PipelineEditorService.$inject = ['JsplumbBridge'];
\ No newline at end of file
diff --git a/ui/src/app/editor/services/pipeline-element-dragged.service.ts b/ui/src/app/editor/services/pipeline-element-dragged.service.ts
new file mode 100644
index 0000000..e209ee4
--- /dev/null
+++ b/ui/src/app/editor/services/pipeline-element-dragged.service.ts
@@ -0,0 +1,31 @@
+/*
+ * 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 {Injectable} from "@angular/core";
+import {Subject} from "rxjs";
+import {PipelineElementPosition} from "../model/editor.model";
+
+@Injectable()
+export class PipelineElementDraggedService {
+
+ public pipelineElementMovedSubject: Subject<PipelineElementPosition> = new Subject<PipelineElementPosition>();
+
+ public notify(position: PipelineElementPosition): void {
+ this.pipelineElementMovedSubject.next(position);
+ }
+}
diff --git a/ui/src/app/editor/services/pipeline-element-recommendation.service.ts b/ui/src/app/editor/services/pipeline-element-recommendation.service.ts
index 3696e3e..d8df30c 100644
--- a/ui/src/app/editor/services/pipeline-element-recommendation.service.ts
+++ b/ui/src/app/editor/services/pipeline-element-recommendation.service.ts
@@ -20,9 +20,9 @@ import {Injectable} from "@angular/core";
import {EditorService} from "./editor.service";
import {PipelineElementUnion} from "../model/editor.model";
import {
- InvocableStreamPipesEntity,
- PipelineElementRecommendation,
- SpDataStream
+ InvocableStreamPipesEntity,
+ PipelineElementRecommendation,
+ SpDataStream
} from "../../core-model/gen/streampipes-model";
@Injectable()
@@ -61,4 +61,4 @@ export class PipelineElementRecommendationService {
.filter(pe => (pe instanceof SpDataStream && pe.elementId === belongsTo)
|| (pe instanceof InvocableStreamPipesEntity && pe.belongsTo === belongsTo));
}
-}
\ No newline at end of file
+}
diff --git a/ui/src/app/editor/services/pipeline-positioning.service.ts b/ui/src/app/editor/services/pipeline-positioning.service.ts
index 2963125..ef03614 100644
--- a/ui/src/app/editor/services/pipeline-positioning.service.ts
+++ b/ui/src/app/editor/services/pipeline-positioning.service.ts
@@ -16,120 +16,118 @@
*
*/
-//import * from 'lodash';
import * as dagre from "dagre";
import {JsplumbBridge} from "./jsplumb-bridge.service";
import {JsplumbConfigService} from "./jsplumb-config.service";
import {JsplumbService} from "./jsplumb.service";
import {Injectable} from "@angular/core";
import {PipelineElementConfig} from "../model/editor.model";
-
-declare const jsPlumb: any;
+import {
+ DataProcessorInvocation,
+ DataSinkInvocation,
+ SpDataStream
+} from "../../core-model/gen/streampipes-model";
+import {JsplumbFactoryService} from "./jsplumb-factory.service";
+import {ObjectProvider} from "./object-provider.service";
@Injectable()
export class PipelinePositioningService {
-
constructor(private JsplumbService: JsplumbService,
private JsplumbConfigService: JsplumbConfigService,
- private JsplumbBridge: JsplumbBridge) {
+ private JsplumbFactoryService: JsplumbFactoryService,
+ private ObjectProvider: ObjectProvider) {
}
- displayPipeline(rawPipelineModel: PipelineElementConfig[], targetCanvas, isPreview, autoLayout) {
- var jsplumbConfig = isPreview ? this.JsplumbConfigService.getPreviewConfig() : this.JsplumbConfigService.getEditorConfig();
-
- for (var i = 0; i < rawPipelineModel.length; i++) {
- var currentPe = rawPipelineModel[i];
+ displayPipeline(rawPipelineModel: PipelineElementConfig[],
+ targetCanvas,
+ previewConfig: boolean,
+ autoLayout: boolean) {
+ let jsPlumbBridge = this.JsplumbFactoryService.getJsplumbBridge(previewConfig);
+ let jsplumbConfig = previewConfig ? this.JsplumbConfigService.getPreviewConfig() : this.JsplumbConfigService.getEditorConfig();
+ rawPipelineModel.forEach(currentPe => {
if (!currentPe.settings.disabled) {
- if (currentPe.type === "stream") {
- this.JsplumbService.streamDropped(currentPe.payload.dom, currentPe.payload, true, isPreview);
+ if (currentPe.type === "stream" || currentPe.type === "set") {
+ this.JsplumbService.dataStreamDropped(currentPe.payload.dom,
+ currentPe.payload as SpDataStream,
+ true,
+ previewConfig);
}
if (currentPe.type === "sepa") {
- this.JsplumbService.sepaDropped(currentPe.payload.dom, currentPe.payload, true, isPreview);
+ this.JsplumbService.dataProcessorDropped(currentPe.payload.dom, currentPe.payload as DataProcessorInvocation, true, previewConfig);
}
if (currentPe.type === "action") {
- this.JsplumbService.actionDropped(currentPe.payload.dom, currentPe.payload, true, isPreview);
+ this.JsplumbService.dataSinkDropped(currentPe.payload.dom, currentPe.payload as DataSinkInvocation, true, previewConfig);
}
}
- }
+ });
- this.connectPipelineElements(rawPipelineModel, !isPreview, jsplumbConfig);
+ this.connectPipelineElements(rawPipelineModel, previewConfig, jsplumbConfig, jsPlumbBridge);
if (autoLayout) {
- this.layoutGraph(targetCanvas, "span[id^='jsplumb']", isPreview ? 75 : 110, isPreview);
+ this.layoutGraph(targetCanvas, "span[id^='jsplumb']", previewConfig ? 75 : 110, previewConfig);
}
- this.JsplumbBridge.repaintEverything();
+ jsPlumbBridge.repaintEverything();
}
layoutGraph(canvas, nodeIdentifier, dimension, isPreview) {
+ let jsPlumbBridge = this.JsplumbFactoryService.getJsplumbBridge(isPreview);
var g = new dagre.graphlib.Graph();
g.setGraph({rankdir: "LR", ranksep: isPreview ? "50" : "100"});
g.setDefaultEdgeLabel(function () {
return {};
});
- var nodes = $(canvas).find(nodeIdentifier).get();
- for (var i = 0; i < nodes.length; i++) {
- var n = nodes[i];
+ var nodes = $(canvas).find(nodeIdentifier).get();
+ nodes.forEach((n, index) => {
g.setNode(n.id, {label: n.id, width: dimension, height: dimension});
- }
- var edges = this.JsplumbBridge.getAllConnections();
- for (var i = 0; i < edges.length; i++) {
- var c = edges[i];
- g.setEdge(c.source.id, c.target.id);
- }
+ });
+
+ var edges = jsPlumbBridge.getAllConnections();
+ edges.forEach(edge => {
+ g.setEdge(edge.source.id, edge.target.id);
+ });
+
dagre.layout(g);
g.nodes().forEach(v => {
- $("#" + v).css("left", g.node(v).x + "px");
- $("#" + v).css("top", g.node(v).y + "px");
+ $(`#${v}`).css("left", g.node(v).x + "px");
+ $(`#${v}`).css("top", g.node(v).y + "px");
});
}
- connectPipelineElements(rawPipelineModel: PipelineElementConfig[], detachable, jsplumbConfig) {
+ connectPipelineElements(rawPipelineModel: PipelineElementConfig[],
+ previewConfig: boolean,
+ jsplumbConfig: any,
+ jsPlumbBridge: JsplumbBridge) {
var source, target;
-
- this.JsplumbBridge.setSuspendDrawing(true);
+ jsPlumbBridge.setSuspendDrawing(true);
for (var i = 0; i < rawPipelineModel.length; i++) {
var pe = rawPipelineModel[i];
- if (pe.type == "sepa") {
- if (pe.payload.connectedTo) {
- for (var j = 0, connection; connection = pe.payload.connectedTo[j]; j++) {
+ if (pe.type == "sepa" || pe.type == "action") {
+ if (!(pe.settings.disabled) && pe.payload.connectedTo) {
+ pe.payload.connectedTo.forEach((connection, index) => {
source = connection;
target = pe.payload.dom;
- var options;
- var id = "#" + source;
- if ($(id).hasClass("sepa")) {
- options = jsplumbConfig.sepaEndpointOptions;
- } else {
- options = jsplumbConfig.streamEndpointOptions;
- }
-
let sourceEndpointId = "out-" + connection;
- let targetEndpointId = "in-" + j + "-" + pe.payload.dom;
- this.JsplumbBridge.connect(
- {uuids: [sourceEndpointId, targetEndpointId], detachable: detachable}
+ let inTargetEndpointId = "in-" + index + "-" + pe.payload.dom;
+ jsPlumbBridge.connect(
+ {
+ uuids: [sourceEndpointId, inTargetEndpointId],
+ detachable: !previewConfig
+ }
);
- }
- }
- } else if (pe.type == "action") {
- target = pe.payload.dom;
+ jsPlumbBridge.activateEndpointWithType(sourceEndpointId, true, "token");
+ jsPlumbBridge.activateEndpointWithType(inTargetEndpointId, true, "token");
- if (pe.payload.connectedTo) {
- for (var j = 0, connection; connection = pe.payload.connectedTo[j]; j++) {
- source = connection;
- let sourceEndpointId = "out-" + connection;
- let targetEndpointId = "in-" + j + "-" + target;
- this.JsplumbBridge.connect(
- {uuids: [sourceEndpointId, targetEndpointId], detachable: detachable}
- );
- }
+ if (!(pe.payload instanceof DataSinkInvocation) && !(this.ObjectProvider.hasConnectedPipelineElement(pe.payload.dom, rawPipelineModel))) {
+ let outTargetEndpointId = "out-" + pe.payload.dom;
+ jsPlumbBridge.activateEndpointWithType(outTargetEndpointId, true, "token");
+ }
+ });
}
}
}
- this.JsplumbBridge.setSuspendDrawing(false, true);
+ jsPlumbBridge.setSuspendDrawing(false, true);
}
-
}
-
-//PipelinePositioningService.$inject = ['JsplumbService', 'JsplumbConfigService', 'JsplumbBridge'];
\ No newline at end of file
diff --git a/ui/src/app/editor/services/pipeline-validation.service.ts b/ui/src/app/editor/services/pipeline-validation.service.ts
index 53f7bb3..24a3df2 100644
--- a/ui/src/app/editor/services/pipeline-validation.service.ts
+++ b/ui/src/app/editor/services/pipeline-validation.service.ts
@@ -21,6 +21,7 @@ import {JsplumbBridge} from "./jsplumb-bridge.service";
import {Injectable} from "@angular/core";
import {PipelineElementConfig} from "../model/editor.model";
import {DataProcessorInvocation, DataSinkInvocation} from "../../core-model/gen/streampipes-model";
+import {JsplumbFactoryService} from "./jsplumb-factory.service";
@Injectable()
export class PipelineValidationService {
@@ -36,10 +37,11 @@ export class PipelineValidationService {
{title: "Did you configure all elements?", content: "There's a pipeline element which is missing some configuration."},
];
- constructor(private JsplumbBridge: JsplumbBridge) {
+ constructor(private JsplumbFactoryService: JsplumbFactoryService) {
}
- isValidPipeline(rawPipelineModel) {
+ isValidPipeline(rawPipelineModel, previewConfig: boolean) {
+ let jsplumbBridge = this.JsplumbFactoryService.getJsplumbBridge(previewConfig);
let streamInAssembly = this.isStreamInAssembly(rawPipelineModel);
let sepaInAssembly = this.isSepaInAssembly(rawPipelineModel);
let actionInAssembly = this.isActionInAssembly(rawPipelineModel);
@@ -48,12 +50,12 @@ export class PipelineValidationService {
let allElementsConfigured = true;
if (streamInAssembly && (sepaInAssembly || actionInAssembly)) {
- allElementsConnected = this.allElementsConnected(rawPipelineModel);
+ allElementsConnected = this.allElementsConnected(rawPipelineModel, jsplumbBridge);
allElementsConfigured = this.allElementsConfigured(rawPipelineModel);
}
if (streamInAssembly && actionInAssembly && allElementsConnected) {
- onlyOnePipelineCreated = this.onlyOnePipelineCreated(rawPipelineModel);
+ onlyOnePipelineCreated = this.onlyOnePipelineCreated(rawPipelineModel, jsplumbBridge);
}
if (!this.isEmptyPipeline(rawPipelineModel)) {
@@ -96,12 +98,12 @@ export class PipelineValidationService {
.every(config => config.settings.completed);
}
- allElementsConnected(rawPipelineModel) {
- let g = this.makeGraph(rawPipelineModel);
- return g.nodes().every(node => this.isFullyConnected(g, node, rawPipelineModel));
+ allElementsConnected(rawPipelineModel, jsplumbBridge) {
+ let g = this.makeGraph(rawPipelineModel, jsplumbBridge);
+ return g.nodes().every(node => this.isFullyConnected(g, node));
}
- isFullyConnected(g, node, rawPipelineModel) {
+ isFullyConnected(g, node) {
var nodeProperty = g.node(node);
return g.outEdges(node).length >= nodeProperty.endpointCount;
}
@@ -118,8 +120,8 @@ export class PipelineValidationService {
return this.isInAssembly(rawPipelineModel, "sepa");
}
- onlyOnePipelineCreated(rawPipelineModel) {
- let g = this.makeGraph(rawPipelineModel);
+ onlyOnePipelineCreated(rawPipelineModel, jsplumbBridge: JsplumbBridge) {
+ let g = this.makeGraph(rawPipelineModel, jsplumbBridge);
let tarjan = dagre.graphlib.alg.tarjan(g);
return tarjan.length == 1;
@@ -135,7 +137,7 @@ export class PipelineValidationService {
return isElementInAssembly;
}
- makeGraph(rawPipelineModel: PipelineElementConfig[]) {
+ makeGraph(rawPipelineModel: PipelineElementConfig[], jsplumbBridge: JsplumbBridge) {
var g = new dagre.graphlib.Graph();
g.setGraph({rankdir: "LR"});
g.setDefaultEdgeLabel(function () {
@@ -151,28 +153,20 @@ export class PipelineValidationService {
label: n.id,
type: elementOptions.type,
name: elementOptions.payload.name,
- endpointCount: this.JsplumbBridge.getEndpointCount(n.id)
+ endpointCount: jsplumbBridge.getEndpointCount(n.id)
});
}
}
- var edges = this.JsplumbBridge.getAllConnections();
- for (var i = 0; i < edges.length; i++) {
+ var edges = jsplumbBridge.getAllConnections();
+ edges.forEach((edge, i) => {
var c = edges[i];
g.setEdge(c.source.id, c.target.id);
g.setEdge(c.target.id, c.source.id);
- }
+ });
return g;
}
getElementOptions(id, rawPipelineModel: PipelineElementConfig[]) {
- var pipelineElement;
- rawPipelineModel.forEach(pe => {
- if (pe.payload.dom === id) {
- pipelineElement = pe;
- }
- });
- return pipelineElement;
+ return rawPipelineModel.find(pe => pe.payload.dom === id);
}
}
-
-//PipelineValidationService.$inject=['ObjectProvider', 'JsplumbBridge'];
\ No newline at end of file
diff --git a/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.ts b/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.ts
index 1fe08db..9125e2f 100644
--- a/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.ts
+++ b/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.ts
@@ -21,8 +21,8 @@ import {Pipeline} from "../../../core-model/gen/streampipes-model";
import {PipelineElementConfig, PipelineElementUnion} from "../../../editor/model/editor.model";
import {PipelinePositioningService} from "../../../editor/services/pipeline-positioning.service";
import {JsplumbService} from "../../../editor/services/jsplumb.service";
-import {JsplumbBridge} from "../../../editor/services/jsplumb-bridge.service";
import {ObjectProvider} from "../../../editor/services/object-provider.service";
+import {JsplumbFactoryService} from "../../../editor/services/jsplumb-factory.service";
@Component({
selector: 'pipeline-preview',
@@ -44,7 +44,7 @@ export class PipelinePreviewComponent implements OnInit {
constructor(private PipelinePositioningService: PipelinePositioningService,
private JsplumbService: JsplumbService,
- private JsplumbBridge: JsplumbBridge,
+ private JsplumbFactoryService: JsplumbFactoryService,
private ObjectProvider: ObjectProvider) {
this.PipelinePositioningService = PipelinePositioningService;
this.ObjectProvider = ObjectProvider;
@@ -58,7 +58,7 @@ export class PipelinePreviewComponent implements OnInit {
this.PipelinePositioningService.displayPipeline(this.rawPipelineModel, elid, true, true);
var existingEndpointIds = [];
setTimeout(() => {
- this.JsplumbBridge.selectEndpoints().each(endpoint => {
+ this.JsplumbFactoryService.getJsplumbBridge(true).selectEndpoints().each(endpoint => {
if (existingEndpointIds.indexOf(endpoint.element.id) === -1) {
$(endpoint.element).click(() => {
let payload = this.ObjectProvider.findElement(endpoint.element.id, this.rawPipelineModel).payload;
@@ -71,4 +71,4 @@ export class PipelinePreviewComponent implements OnInit {
});
});
}
-}
\ No newline at end of file
+}
diff --git a/ui/src/scss/main.scss b/ui/src/scss/main.scss
index 3c96525..020b977 100644
--- a/ui/src/scss/main.scss
+++ b/ui/src/scss/main.scss
@@ -24,7 +24,7 @@
@import '~bootstrap/dist/css/bootstrap.css';
@import '~@fortawesome/fontawesome-free/css/all.css';
@import '~angular-ui-tree/dist/angular-ui-tree.min.css';
-@import '~jsplumb/dist/css/jsplumb.css';
+@import '~jsplumb/css/jsplumbtoolkit-defaults.css';
@import '~ng-prettyjson/dist/ng-prettyjson.min.css';
@import '~prismjs/themes/prism.css';
@import '~angular-loading-bar/build/loading-bar.min.css';
@@ -35,6 +35,7 @@
//@import '~material-design-icons/iconfont/material-icons.css';
@import '~quill/dist/quill.snow.css';
@import '~swagger-ui/dist/swagger-ui.css';
+@import '~perfect-scrollbar/css/perfect-scrollbar.css';
@import '~roboto-fontface/css/roboto/roboto-fontface.css';
@@ -60,6 +61,7 @@
@import './sp/pipeline-assembly.scss';
@import './sp/widgets.scss';
@import './sp/progress-bar.scss';
+@import './sp/jsplumb';
@import './sp/input.ng1';
@import './sp/documentation.ng1';
diff --git a/ui/src/scss/sp/jsplumb.scss b/ui/src/scss/sp/jsplumb.scss
new file mode 100644
index 0000000..9d828b5
--- /dev/null
+++ b/ui/src/scss/sp/jsplumb.scss
@@ -0,0 +1,21 @@
+/*!
+ * 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.
+ *
+ */
+
+.jtk-endpoint {
+ z-index: 5;
+}
diff --git a/ui/src/scss/sp/main.scss b/ui/src/scss/sp/main.scss
index 4185bdb..3d1044e 100644
--- a/ui/src/scss/sp/main.scss
+++ b/ui/src/scss/sp/main.scss
@@ -22,6 +22,10 @@ md-progress-linear.md-accent .md-container {
background-color: rgb(168, 168, 168);
}
+.stream-endpoint {
+ background: green;
+}
+
.gu-mirror {
display: none; /* This fixes a bug with the dragular framework */
}
@@ -517,10 +521,6 @@ md-select.md-default-theme .md-select-value.md-select-placeholder, md-select .md
border: 2px solid $sp-color-accent !important;
}
-.jsplumb-endpoint {
- z-index: 5;
-}
-
.popover {
border: 1px solid $sp-color-accent;
box-shadow: 0 0px 0px;