save and query workflow definition 49/9249/1
authorLvbo163 <lv.bo163@zte.com.cn>
Wed, 30 Aug 2017 01:21:09 +0000 (09:21 +0800)
committerLvbo163 <lv.bo163@zte.com.cn>
Wed, 30 Aug 2017 01:29:32 +0000 (09:29 +0800)
add in memory web api to mock backend rest api to save and load workflow definition.

Issue-ID: SDC-257

Change-Id: Ibedcbe5db5706773de9f6d1093babbcbd7b73297
Signed-off-by: Lvbo163 <lv.bo163@zte.com.cn>
17 files changed:
sdc-workflow-designer-ui/package-lock.json
sdc-workflow-designer-ui/package.json
sdc-workflow-designer-ui/src/app/app.component.html
sdc-workflow-designer-ui/src/app/app.component.ts
sdc-workflow-designer-ui/src/app/app.module.ts
sdc-workflow-designer-ui/src/app/components/toolbar/toolbar.component.html
sdc-workflow-designer-ui/src/app/components/toolbar/toolbar.component.ts
sdc-workflow-designer-ui/src/app/model/workflow.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/services/data-access/catalog.service.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/services/data-access/data-access.service.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/services/data-access/in-memory-data.service.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/services/data-access/sdc.service.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/services/workflow.service.ts
sdc-workflow-designer-ui/src/app/shared/shared.module.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/util/http.service.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/util/rxjs-operators.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/index.html

index 5cfcfbf..8a9931b 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "workflow-designer",
-  "version": "0.0.0",
+  "version": "1.0.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
       "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
       "dev": true
     },
+    "angular-in-memory-web-api": {
+      "version": "0.3.2",
+      "resolved": "http://10.75.8.148/repository/npm-pub/angular-in-memory-web-api/-/angular-in-memory-web-api-0.3.2.tgz",
+      "integrity": "sha1-iDbZ4lNNN7co88taHK9v4ef7vs0="
+    },
     "ansi-escapes": {
       "version": "2.0.0",
       "resolved": "http://registry.npm.taobao.org/ansi-escapes/download/ansi-escapes-2.0.0.tgz",
index 07b68ff..1489a8c 100644 (file)
@@ -21,6 +21,7 @@
     "@angular/platform-browser": "^4.2.4",
     "@angular/platform-browser-dynamic": "^4.2.4",
     "@angular/router": "^4.2.4",
+    "angular-in-memory-web-api": "^0.3.2",
     "core-js": "^2.4.1",
     "jsplumb": "2.5.0",
     "rxjs": "^5.4.2",
index f09e0a7..f666c1b 100644 (file)
@@ -17,6 +17,6 @@
 <b4t-toolbar></b4t-toolbar>
 
 <div id="container" class="container">
-    <b4t-node *ngFor="let node of getNodes(); let last = last;" [node]="node" [last]="last"></b4t-node>
+    <b4t-node *ngFor="let node of getWorkflow()?.nodes; let last = last;" [node]="node" [last]="last"></b4t-node>
 </div>
 
index b02ce67..59b457f 100644 (file)
  *     ZTE - initial API and implementation and/or initial documentation
  */
 
-import { Component, AfterViewInit } from '@angular/core';
+import { Component, AfterViewInit, OnInit } from '@angular/core';
 import { JsPlumbService } from "./services/jsplumb.service";
 import { WorkflowService } from "./services/workflow.service";
 import { WorkflowNode } from "./model/workflow-node";
+import { Workflow } from "./model/workflow";
+import { DataAccessService } from "./services/data-access/data-access.service";
 
 @Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
 })
-export class AppComponent implements AfterViewInit {
-    constructor(private jsplumbService: JsPlumbService, private workflowService: WorkflowService) {}
+export class AppComponent implements AfterViewInit, OnInit {
+    constructor(private jsplumbService: JsPlumbService,
+        private dataAccessService: DataAccessService,
+        private workflowService: WorkflowService) {}
 
-    public getNodes(): WorkflowNode[] {
-        return this.workflowService.getNodes();
+    ngOnInit(): void {
+        this.dataAccessService.catalogService.loadWorkflow('workflow1').subscribe(workflow => {
+            this.workflowService.workflow = workflow;
+        });
+    }
+
+    public getWorkflow(): Workflow {
+        return this.workflowService.workflow;
     }
 
     ngAfterViewInit(): void {
index 3d57ce1..616db2d 100644 (file)
@@ -18,6 +18,12 @@ import { JsPlumbService } from "./services/jsplumb.service";
 import { NodeComponent } from "./components/node/node.component";
 import { ToolbarComponent } from "./components/toolbar/toolbar.component";
 import { WorkflowService } from "./services/workflow.service";
+import { DataAccessService } from "./services/data-access/data-access.service";
+import { HttpService } from "./util/http.service";
+import { SharedModule } from "./shared/shared.module";
+import { InMemoryWebApiModule } from "angular-in-memory-web-api";
+import { InMemoryDataService } from "./services/data-access/in-memory-data.service";
+import { HttpModule } from "@angular/http";
 
 @NgModule({
     declarations: [
@@ -26,9 +32,17 @@ import { WorkflowService } from "./services/workflow.service";
         ToolbarComponent,
     ],
     imports: [
-        BrowserModule
+        BrowserModule,
+        HttpModule,
+        InMemoryWebApiModule.forRoot(InMemoryDataService),
+        SharedModule,
+    ],
+    providers: [
+        DataAccessService,
+        HttpService,
+        JsPlumbService,
+        WorkflowService
     ],
-    providers: [JsPlumbService, WorkflowService],
     bootstrap: [AppComponent]
 })
 export class AppModule { }
index 5d028b9..91b935e 100644 (file)
@@ -19,5 +19,7 @@
         <button type="button" class="btn btn-secondary item ui-draggable" [attr.nodeType]="'endEvent'">\r
             <span>endEvent</span>\r
         </button>\r
+\r
+        <button type="button" class="btn btn-success" (click)="save()">Save</button>\r
     </div>\r
 </div>\r
index 5fdb6ce..1e1de19 100644 (file)
@@ -13,6 +13,7 @@
 import { AfterViewInit, Component } from '@angular/core';\r
 \r
 import { JsPlumbService } from '../../services/jsplumb.service';\r
+import { WorkflowService } from "../../services/workflow.service";\r
 \r
 /**\r
  * toolbar component contains some basic operations(save) and all of the supported workflow nodes.\r
@@ -25,11 +26,21 @@ import { JsPlumbService } from '../../services/jsplumb.service';
 })\r
 export class ToolbarComponent implements AfterViewInit {\r
 \r
-    constructor(private jsPlumbService: JsPlumbService) {\r
+    constructor(private jsPlumbService: JsPlumbService, private workflowService: WorkflowService) {\r
     }\r
 \r
     public ngAfterViewInit() {\r
         this.jsPlumbService.buttonDraggable();\r
     }\r
 \r
+    public save() {\r
+        this.workflowService.save().subscribe(success => {\r
+            if(success) {\r
+                console.log(`save workflow success`);\r
+            } else {\r
+                console.log(`save workflow failed`);\r
+            }\r
+        });\r
+    }\r
+\r
 }\r
diff --git a/sdc-workflow-designer-ui/src/app/model/workflow.ts b/sdc-workflow-designer-ui/src/app/model/workflow.ts
new file mode 100644 (file)
index 0000000..672396c
--- /dev/null
@@ -0,0 +1,21 @@
+/**\r
+ * Copyright (c) 2017 ZTE Corporation.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * and the Apache License 2.0 which both accompany this distribution,\r
+ * and are available at http://www.eclipse.org/legal/epl-v10.html\r
+ * and http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Contributors:\r
+ *     ZTE - initial API and implementation and/or initial documentation\r
+ */\r
+\r
+import { Injectable } from '@angular/core';\r
+import { WorkflowNode } from "./workflow-node";\r
+\r
+/**\r
+ * Workflow\r
+ */\r
+export class Workflow {\r
+    constructor(public id: string, public name: string, public nodes: WorkflowNode[]) {}\r
+}\r
diff --git a/sdc-workflow-designer-ui/src/app/services/data-access/catalog.service.ts b/sdc-workflow-designer-ui/src/app/services/data-access/catalog.service.ts
new file mode 100644 (file)
index 0000000..5eaf635
--- /dev/null
@@ -0,0 +1,31 @@
+/**\r
+ * Copyright (c) 2017 ZTE Corporation.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * and the Apache License 2.0 which both accompany this distribution,\r
+ * and are available at http://www.eclipse.org/legal/epl-v10.html\r
+ * and http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Contributors:\r
+ *     ZTE - initial API and implementation and/or initial documentation\r
+ */\r
+\r
+import { Injectable } from '@angular/core';\r
+import { WorkflowNode } from "../../model/workflow-node";\r
+import { Observable } from "rxjs/Observable";\r
+import { HttpService } from "../../util/http.service";\r
+import { Workflow } from "../../model/workflow";\r
+\r
+/**\r
+ * CatalogService\r
+ * provides data access from backend\r
+ */\r
+@Injectable()\r
+export abstract class CatalogService {\r
+\r
+    constructor(protected httpService: HttpService) {}\r
+\r
+    public abstract loadWorkflow(workflowId: string): Observable<Workflow>;\r
+\r
+    public abstract saveWorkflow(workflow: Workflow): Observable<boolean>;\r
+}\r
diff --git a/sdc-workflow-designer-ui/src/app/services/data-access/data-access.service.ts b/sdc-workflow-designer-ui/src/app/services/data-access/data-access.service.ts
new file mode 100644 (file)
index 0000000..451d7a2
--- /dev/null
@@ -0,0 +1,27 @@
+/**\r
+ * Copyright (c) 2017 ZTE Corporation.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * and the Apache License 2.0 which both accompany this distribution,\r
+ * and are available at http://www.eclipse.org/legal/epl-v10.html\r
+ * and http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Contributors:\r
+ *     ZTE - initial API and implementation and/or initial documentation\r
+ */\r
+\r
+import { Injectable } from '@angular/core';\r
+import { CatalogService } from "./catalog.service";\r
+import { SdcService } from "./sdc.service";\r
+import { HttpService } from "../../util/http.service";\r
+\r
+/**\r
+ * DataAccessService\r
+ * provides data access from backend\r
+ */\r
+@Injectable()\r
+export class DataAccessService {\r
+    constructor(private httpService: HttpService) {}\r
+\r
+    public catalogService: CatalogService = new SdcService(this.httpService);\r
+}\r
diff --git a/sdc-workflow-designer-ui/src/app/services/data-access/in-memory-data.service.ts b/sdc-workflow-designer-ui/src/app/services/data-access/in-memory-data.service.ts
new file mode 100644 (file)
index 0000000..1609c94
--- /dev/null
@@ -0,0 +1,33 @@
+/**\r
+ * Copyright (c) 2017 ZTE Corporation.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * and the Apache License 2.0 which both accompany this distribution,\r
+ * and are available at http://www.eclipse.org/legal/epl-v10.html\r
+ * and http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Contributors:\r
+ *     ZTE - initial API and implementation and/or initial documentation\r
+ */\r
+\r
+import { Injectable } from '@angular/core';\r
+import { InMemoryDbService } from 'angular-in-memory-web-api';\r
+/**\r
+ * InMemeoryDataService\r
+ * Mock backend data\r
+ */\r
+export class InMemoryDataService implements InMemoryDbService {\r
+    createDb() {\r
+        const workflows = [{\r
+            id: 'workflow1',\r
+            name:'workflow1',\r
+            nodes: []\r
+        },{\r
+            id:'workflow2',\r
+            name: 'workflow2',\r
+            nodes: []\r
+        }\r
+    ];\r
+        return {workflows};\r
+    }\r
+}\r
diff --git a/sdc-workflow-designer-ui/src/app/services/data-access/sdc.service.ts b/sdc-workflow-designer-ui/src/app/services/data-access/sdc.service.ts
new file mode 100644 (file)
index 0000000..cec6ae2
--- /dev/null
@@ -0,0 +1,49 @@
+/**\r
+ * Copyright (c) 2017 ZTE Corporation.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * and the Apache License 2.0 which both accompany this distribution,\r
+ * and are available at http://www.eclipse.org/legal/epl-v10.html\r
+ * and http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Contributors:\r
+ *     ZTE - initial API and implementation and/or initial documentation\r
+ */\r
+\r
+import { Injectable } from '@angular/core';\r
+import { CatalogService } from "./catalog.service";\r
+import { Observable } from "rxjs/Observable";\r
+import { WorkflowNode } from "../../model/workflow-node";\r
+import { HttpService } from "../../util/http.service";\r
+import { Workflow } from "../../model/workflow";\r
+\r
+/**\r
+ * SdcService\r
+ * provides data access from sdc\r
+ */\r
+@Injectable()\r
+export class SdcService extends CatalogService {\r
+\r
+    constructor(protected httpService: HttpService) {\r
+        super(httpService);\r
+    }\r
+\r
+    public loadWorkflows(): Observable<WorkflowNode[]> {\r
+        // TODO load data from sdc\r
+        const url = 'api/workflows';\r
+        return this.httpService.get(url);\r
+    }\r
+\r
+    public loadWorkflow(workflowId: string): Observable<Workflow> {\r
+        // TODO load data from sdc\r
+        const url = `api/workflows/${workflowId}`;\r
+        return this.httpService.get(url).map(response => response.data);\r
+    }\r
+\r
+    public saveWorkflow(workflow: Workflow): Observable<boolean> {\r
+        // TODO save workflow design to sdc\r
+        const url = `api/workflows/${workflow.id}`;\r
+        return this.httpService.put(url, JSON.stringify(workflow)).map(() => true);\r
+    }\r
+\r
+}\r
index 59e1fd5..d9a949e 100644 (file)
@@ -12,6 +12,9 @@
 \r
 import { Injectable } from '@angular/core';\r
 import { WorkflowNode } from "../model/workflow-node";\r
+import { DataAccessService } from "./data-access/data-access.service";\r
+import { Observable } from "rxjs/Observable";\r
+import { Workflow } from "../model/workflow";\r
 \r
 /**\r
  * WorkflowService\r
@@ -19,34 +22,41 @@ import { WorkflowNode } from "../model/workflow-node";
  */\r
 @Injectable()\r
 export class WorkflowService {\r
-    public nodes: WorkflowNode[] = [];\r
 \r
-    public getNodes(): WorkflowNode[] {\r
-        return this.nodes;\r
+    public workflow: Workflow;\r
+\r
+    constructor(private dataAccessService: DataAccessService) {\r
+\r
+    }\r
+\r
+    public save(): Observable<boolean> {\r
+        return this.dataAccessService.catalogService.saveWorkflow(this.workflow);\r
     }\r
 \r
-    public addNode(name: string, type: string,  top: number, left: number) {\r
-        this.nodes.push(new WorkflowNode(this.createId(), name, type, top, left));\r
+    public addNode(name: string, type: string, top: number, left: number): WorkflowNode {\r
+        const node = new WorkflowNode(this.createId(), name, type, top, left);\r
+        this.workflow.nodes.push(node);\r
+        return node;\r
     }\r
 \r
     public deleteNode(nodeId: string): WorkflowNode {\r
         // delete current node\r
-        const index = this.nodes.findIndex(node => node.id === nodeId);\r
+        const index = this.workflow.nodes.findIndex(node => node.id === nodeId);\r
         if (index !== -1) {\r
-            const node = this.nodes.splice(index, 1)[0];\r
+            const node = this.workflow.nodes.splice(index, 1)[0];\r
             return node;\r
         }\r
 \r
         return undefined;\r
     }\r
 \r
-    public getNode(sourceId: string): WorkflowNode {\r
-        return this.nodes.find(node => node.id === sourceId);\r
+    public getNodeById(sourceId: string): WorkflowNode {\r
+        return this.workflow.nodes.find(node => node.id === sourceId);\r
     }\r
 \r
     private createId() {\r
         const idSet = new Set();\r
-        this.nodes.forEach(node => idSet.add(node.id));\r
+        this.workflow.nodes.forEach(node => idSet.add(node.id));\r
 \r
         for (let i = 0; i < idSet.size; i++) {\r
             if (!idSet.has('node' + i)) {\r
diff --git a/sdc-workflow-designer-ui/src/app/shared/shared.module.ts b/sdc-workflow-designer-ui/src/app/shared/shared.module.ts
new file mode 100644 (file)
index 0000000..baf1dba
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 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 { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { HttpModule } from '@angular/http';
+import { RouterModule } from '@angular/router';
+
+const module = [
+    CommonModule,
+    FormsModule,
+    RouterModule,
+];
+
+@NgModule({
+    imports: module,
+    exports: module,
+})
+
+export class SharedModule {
+}
diff --git a/sdc-workflow-designer-ui/src/app/util/http.service.ts b/sdc-workflow-designer-ui/src/app/util/http.service.ts
new file mode 100644 (file)
index 0000000..3266955
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * 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 { Http, RequestOptionsArgs } from '@angular/http';
+import { Observable } from 'rxjs/Rx';
+import './rxjs-operators';
+
+@Injectable()
+export class HttpService {
+    constructor(private http: Http) {}
+
+    public get(uri: string): Observable<any> {
+        return this.getHttp('get', uri);
+    }
+
+    public post(uri: string, data: any): Observable<any> {
+        return this.getHttp('post', uri, data);
+    }
+
+    public put(uri: string, data: any, options?: RequestOptionsArgs): Observable<any> {
+        return this.getHttp('put', uri, data, options);
+    }
+
+    public delete(uri: string): Observable<any> {
+        return this.getHttp('delete', uri);
+    }
+
+    public getHttp(type: string, uri: string, data?: any, options?: RequestOptionsArgs): Observable<any> {
+        if (data) {
+            return this.http[type](uri, data, options)
+                .map(response =>
+                    response.json()
+                )
+                .catch(this.handleError);
+        } else {
+            return this.http[type](uri, options)
+                .map(response =>
+                    response.json()
+                )
+                .catch(this.handleError);
+        }
+    }
+
+    private handleError(error: any) {
+        const errMsg = (error.message) ? error.message :
+            error.status ? `${error.status}-${error.statusText}` : 'Server error';
+        return Observable.throw(errMsg);
+    }
+}
diff --git a/sdc-workflow-designer-ui/src/app/util/rxjs-operators.ts b/sdc-workflow-designer-ui/src/app/util/rxjs-operators.ts
new file mode 100644 (file)
index 0000000..00fa50b
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+ * 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 'rxjs/add/observable/throw';
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/operator/debounceTime';
+import 'rxjs/add/operator/distinctUntilChanged';
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/switchMap';
+import 'rxjs/add/operator/toPromise';
index 1eab7e5..e876fc8 100644 (file)
@@ -16,7 +16,7 @@
 <head>
   <meta charset="utf-8">
   <title>Workflow Designer</title>
-  <base href="/lvbo">
+  <base href="/">
 
   <meta name="viewport" content="width=device-width, initial-scale=1">
 </head>