diff options
author | Lvbo163 <lv.bo163@zte.com.cn> | 2017-08-28 14:19:17 +0800 |
---|---|---|
committer | Lvbo163 <lv.bo163@zte.com.cn> | 2017-08-28 16:23:33 +0800 |
commit | df81658e252dd886f30e984f1aa4a5f3917cd134 (patch) | |
tree | b39bc64ce878902038842b1da412aaba4a2d989f /sdc-workflow-designer-ui/src/app | |
parent | f721b1af7e3496427ee9c46d5bb46103c49505c6 (diff) |
WorkFlow Diagram Editor
create workflow diagram editor area, install jsplumb package to support node drag and node connections.
Change-Id: Ie68d0f88ef1cc855c1e55e51e918111c6fba4116
Issue-ID: SDC-70
Signed-off-by: Lvbo163 <lv.bo163@zte.com.cn>
Diffstat (limited to 'sdc-workflow-designer-ui/src/app')
8 files changed, 402 insertions, 11 deletions
diff --git a/sdc-workflow-designer-ui/src/app/app.component.css b/sdc-workflow-designer-ui/src/app/app.component.css index ad9d91f5..06cc8b00 100644 --- a/sdc-workflow-designer-ui/src/app/app.component.css +++ b/sdc-workflow-designer-ui/src/app/app.component.css @@ -8,4 +8,12 @@ *
* Contributors:
* ZTE - initial API and implementation and/or initial documentation
- */
\ No newline at end of file + */
+
+
+ .container {
+ width: 100%;
+ height: 100%;
+ background-color: cadetblue;
+ }
+
diff --git a/sdc-workflow-designer-ui/src/app/app.component.html b/sdc-workflow-designer-ui/src/app/app.component.html index e2204daf..fe3b4550 100644 --- a/sdc-workflow-designer-ui/src/app/app.component.html +++ b/sdc-workflow-designer-ui/src/app/app.component.html @@ -13,10 +13,8 @@ --> <!--The content below is only a placeholder and can be replaced.--> -<div style="text-align:center"> - <h1> - Welcome to {{title}}! - </h1> -</div> +<div id="container" class="container"> + <b4t-node *ngFor="let node of nodes" [node]="node"></b4t-node> +</div> diff --git a/sdc-workflow-designer-ui/src/app/app.component.ts b/sdc-workflow-designer-ui/src/app/app.component.ts index 76fa7666..32500abb 100644 --- a/sdc-workflow-designer-ui/src/app/app.component.ts +++ b/sdc-workflow-designer-ui/src/app/app.component.ts @@ -10,13 +10,40 @@ * ZTE - initial API and implementation and/or initial documentation */ -import { Component } from '@angular/core'; +import { Component, AfterViewInit } from '@angular/core'; +import { JsPlumbService } from "./services/jsplumb.service"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) -export class AppComponent { - title = 'SDC Workflow Designer'; +export class AppComponent implements AfterViewInit { + constructor(private jsplumbService: JsPlumbService) {} + + public nodes = [ + { + id: '001', + name: 'node001', + top: 50, + left: 50, + }, + { + id: '002', + name: 'node002', + top: 250, + left: 50, + }, + { + id: '003', + name: 'node003', + top: 140, + left: 450, + }, + ]; + + ngAfterViewInit(): void { + this.jsplumbService.initJsPlumbInstance(); + this.jsplumbService.initNode('.node'); + } } diff --git a/sdc-workflow-designer-ui/src/app/app.module.ts b/sdc-workflow-designer-ui/src/app/app.module.ts index 20b217f6..de2b3c08 100644 --- a/sdc-workflow-designer-ui/src/app/app.module.ts +++ b/sdc-workflow-designer-ui/src/app/app.module.ts @@ -14,15 +14,18 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; +import { JsPlumbService } from "./services/jsplumb.service"; +import { NodeComponent } from "./components/node/node.component"; @NgModule({ declarations: [ - AppComponent + AppComponent, + NodeComponent, ], imports: [ BrowserModule ], - providers: [], + providers: [JsPlumbService], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/sdc-workflow-designer-ui/src/app/components/node/node.component.css b/sdc-workflow-designer-ui/src/app/components/node/node.component.css new file mode 100644 index 00000000..24e657ca --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/components/node/node.component.css @@ -0,0 +1,187 @@ + .node {
+ position:absolute;
+ width: 100px;
+ height: 50px;
+ border: 2px solid black;
+ }
+
+
+/**
+ * Anchors
+ */
+.anchors {
+ position: absolute;
+ border-radius: 1em;
+ z-index: 20;
+ display: none;
+ background-color: black;
+ width: 0;
+ height: 0;
+ cursor: pointer;
+ -ms-transition: all 0.15s ease-in-out;
+ transition: all 0.15s ease-in-out;
+ -moz-transition: all 0.15s ease-in-out;
+ -webkit-transition: all 0.15s ease-in-out;
+ -o-transition: all 0.15s ease-in-out;
+}
+
+.node:hover .anchors {
+ background-color: black;
+ display: inline-block;
+ width: 12px;
+ height: 12px;
+ z-index: 20;
+}
+
+.anchor-left {
+ left: -5px;
+ top: 40%;
+}
+
+.anchor-right {
+ right: -5px;
+ top: 40%;
+}
+
+.anchor-top {
+ top: -5px;
+ left: 40%;
+}
+
+.anchor-bottom {
+ bottom: -5px;
+ left: 40%;
+}
+
+/*右箭头*/
+.right {
+ width: 10px;
+ height: 10px;
+ position: absolute;
+ left: 4px;
+ top: 1px;
+
+}
+
+.right-arrow1, .right-arrow2 {
+ width: 0;
+ height: 0;
+ display: block;
+ position: absolute;
+ left: 0;
+ top: 0;
+ border-top: 5px transparent dashed;
+ border-right: 5px transparent dashed;
+ border-bottom: 5px transparent dashed;
+ border-left: 5px black solid;
+ overflow: hidden;
+}
+
+.right-arrow1 {
+
+ border-left: 5px white solid;
+}
+
+.right-arrow2 {
+ left: -2px;
+}
+
+/*左箭头*/
+.left {
+ width: 10px;
+ height: 10px;
+ position: absolute;
+ left: -2px;
+ top: 1px;
+ z-index: 2;
+}
+
+.left-arrow1, .left-arrow2 {
+ width: 0;
+ height: 0;
+ display: block;
+ position: absolute;
+ left: 0;
+ top: 0;
+ z-index: 5; /*兼容ie8-*/
+ border-top: 5px transparent dashed;
+ border-left: 5px transparent dashed;
+ border-bottom: 5px transparent dashed;
+ border-right: 5px black solid;
+ overflow: hidden;
+}
+
+.left-arrow1 {
+ border-right: 5px #fff solid;
+}
+
+.left-arrow2 {
+ left: 2px;
+}
+
+/*上箭头*/
+.top {
+ width: 9px;
+ height: 9px;
+ position: absolute;
+ left: 1px;
+ z-index: 2;
+}
+
+.top-arrow1, .top-arrow2 {
+ width: 0;
+ height: 0;
+ display: block;
+ position: absolute;
+ left: 0;
+ top: 0;
+ z-index: 5;
+ border-bottom: 5px black solid;
+ border-left: 5px transparent dashed;
+ border-right: 5px transparent dashed;
+ border-top: 5px transparent dashed;
+ overflow: hidden;
+}
+
+.top-arrow1 {
+ z-index: 6;
+}
+
+.top-arrow2 {
+ top: -2px;
+ border-bottom: 4px white solid;
+}
+
+/*下箭头*/
+.bottom {
+ width: 9px;
+ height: 9px;
+ position: absolute;
+ left: 1px;
+ top: 4px;
+ z-index: 2;
+}
+
+.bottom-arrow1, .bottom-arrow2 {
+ width: 0;
+ height: 0;
+ display: block;
+ position: absolute;
+ left: 0;
+ top: 0;
+ z-index: 5;
+ border-bottom: 4px transparent dashed;
+ border-left: 4px transparent dashed;
+ border-right: 4px transparent dashed;
+ border-top: 4px black solid;
+ overflow: hidden;
+}
+
+.bottom-arrow1 {
+ top: -2px;
+ z-index: 6;
+}
+
+.bottom-arrow2 {
+ border-top: 4px white solid;
+}
diff --git a/sdc-workflow-designer-ui/src/app/components/node/node.component.html b/sdc-workflow-designer-ui/src/app/components/node/node.component.html new file mode 100644 index 00000000..72700551 --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/components/node/node.component.html @@ -0,0 +1,41 @@ +<!--
+/**
+ * Copyright (c) 2017 ZTE Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ * ZTE - initial API and implementation and/or initial documentation
+ */
+-->
+<div class="node" [style.top]="node.top + 'px'"
+ [style.left]="node.left + 'px'">
+ <div>{{node.name}}</div>
+ <div class="anchor anchors anchor-left">
+ <span class="left">
+ <i class="left-arrow1"></i>
+ <i class="left-arrow2"></i>
+ </span>
+ </div>
+ <div class="anchor anchors anchor-right">
+ <span class="right">
+ <i class="right-arrow1"></i>
+ <i class="right-arrow2"></i>
+ </span>
+ </div>
+ <div class="anchor anchors anchor-top">
+ <span class="top">
+ <i class="top-arrow1"></i>
+ <i class="top-arrow2"></i>
+ </span>
+ </div>
+ <div class="anchor anchors anchor-bottom">
+ <span class="bottom">
+ <i class="bottom-arrow1"></i>
+ <i class="bottom-arrow2"></i>
+ </span>
+ </div>
+</div>
diff --git a/sdc-workflow-designer-ui/src/app/components/node/node.component.ts b/sdc-workflow-designer-ui/src/app/components/node/node.component.ts new file mode 100644 index 00000000..12f23cc5 --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/components/node/node.component.ts @@ -0,0 +1,32 @@ +/**
+ * Copyright (c) 2017 ZTE Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ * ZTE - initial API and implementation and/or initial documentation
+ */
+
+import { Component, AfterViewInit, Input } from '@angular/core';
+
+import { JsPlumbService } from '../../services/jsplumb.service';
+
+/**
+ * workflow node component
+ */
+@Component({
+ selector: 'b4t-node',
+ styleUrls: ['./node.component.css'],
+ templateUrl: 'node.component.html',
+})
+export class NodeComponent {
+ @Input() public node: Node;
+
+ constructor(private jsPlumbService: JsPlumbService) {
+
+ }
+
+}
diff --git a/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts b/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts new file mode 100644 index 00000000..7012ccc3 --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts @@ -0,0 +1,95 @@ +/**
+ * Copyright (c) 2017 ZTE Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ * ZTE - initial API and implementation and/or initial documentation
+ */
+
+import { Injectable } from '@angular/core';
+import * as jsp from 'jsplumb';
+
+/**
+ * JsPlumbService
+ * provides all of the operations about jsplumb plugin.
+ */
+@Injectable()
+export class JsPlumbService {
+ private jsplumbInstance;
+
+ constructor() {
+
+ }
+
+
+ public initJsPlumbInstance() {
+ this.jsplumbInstance = jsp.jsPlumb.getInstance({
+ Container: 'container'
+ });
+
+ this.jsplumbInstance.importDefaults({
+ Anchor: ['Top', 'RightMiddle', 'LeftMiddle', 'Bottom'],
+ Connector: [
+ 'Flowchart',
+ { cornerRadius: 0, stub: 0, gap: 3 },
+ ],
+ ConnectionOverlays: [
+ [
+ 'Arrow',
+ { direction: 1, foldback: 1, location: 1, width: 10, length: 10 },
+ ],
+ ['Label', { label: '', id: 'label', cssClass: 'aLabel' }],
+ ],
+ Endpoint: 'Blank',
+ PaintStyle: {
+ strokeWidth: 4,
+ stroke: 'black',
+ },
+ HoverPaintStyle: {
+ strokeWidth: 4,
+ stroke: 'blue',
+ },
+ });
+
+ // add connection to model data while a new connection is build
+ this.jsplumbInstance.bind('connection', info => {
+ this.jsplumbInstance.bind('connection', info => {
+
+ info.connection.bind('click', connection => {
+ this.jsplumbInstance.select({ connections: [connection] }).delete();
+ });
+ });
+
+ });
+
+ }
+
+ public initNode(selectorString: string) {
+ const selector = this.jsplumbInstance.getSelector(selectorString);
+
+ this.jsplumbInstance.draggable(selector, {
+ // stop(event) {
+ // node.position.left = event.pos[0];
+ // node.position.top = event.pos[1];
+ // },
+ });
+
+ this.jsplumbInstance.makeTarget(selector, {
+ detachable: false,
+ isTarget: true,
+ maxConnections: -1,
+ });
+
+ this.jsplumbInstance.makeSource(selector, {
+ filter: '.anchor, .anchor *',
+ detachable: false,
+ isSource: true,
+ maxConnections: -1,
+ });
+
+ } +}
|