<menus class="design-menus"></menus>
<b4t-container class="design-container"></b4t-container>
</div>
+ <global-notice></global-notice>
</div>
+
+<div *ngIf="isLoading" class="loading-div">
+ <div></div>
+</div>
\ No newline at end of file
* ZTE - initial API and implementation and/or initial documentation
*/
-import { Component, AfterViewInit, OnInit } from '@angular/core';
-import { JsPlumbService } from "./services/jsplumb.service";
-import { WorkflowService } from "./services/workflow.service";
-import { WorkflowNode } from "./model/workflow/workflow-node";
-import { DataAccessService } from "./services/data-access/data-access.service";
-import { ActivatedRoute } from "@angular/router";
+import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { BroadcastService } from './services/broadcast.service';
+/**
+ * main component
+ */
@Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
+ selector: 'workflow',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css']
})
export class AppComponent {
- public isLoading = true;
+ public isLoading = false;
constructor(translate: TranslateService, private broadcastService: BroadcastService) {
// Init the I18n function.
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
-
+import { AlertModule, ModalModule } from 'ngx-bootstrap/index';
import { AccordionModule } from 'ngx-bootstrap/accordion';
import { AppComponent } from './app.component';
import { MicroserviceDetailComponent } from "./components/menus/microservice/microservice-detail/microservice-detail.component";
import { MicroserviceComponent } from "./components/menus/microservice/microservice.component";
import { MicroserviceListComponent } from "./components/menus/microservice/microservice-list/microservice-list.component";
-import { ModalModule } from "ngx-bootstrap/modal";
-import { WorkflowConfigService } from "./services/workflow-config.service";
import { RestTaskComponent } from "./components/property/rest-task/rest-task.component";
import { EditablePropertyComponent } from "./components/editable-property/editable-property.component";
import { SwaggerTreeConverterService } from "./services/swagger-tree-converter.service";
import { NodeParametersComponent } from './components/node-parameters/node-parameters.component';
import { ParameterTreeComponent } from './components/node-parameters/parameter-tree/parameter-tree.component';
import { NoticeService } from './services/notice.service';
+import { GlobalNoticeComponent } from './components/global-notice/global-notice.component';
// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
ContainerComponent,
ResizableDirective,
EditablePropertyComponent,
+ GlobalNoticeComponent,
IntermediateCatchEventComponent,
MenusComponent,
MicroserviceComponent,
NoticeService,
RestService,
SwaggerTreeConverterService,
- WorkflowConfigService,
-
WorkflowService
],
imports: [
AccordionModule.forRoot(),
+ AlertModule.forRoot(),
BrowserAnimationsModule,
BrowserModule,
HttpModule,
import { MicroserviceComponent } from "./microservice/microservice.component";
import { WorkflowsComponent } from "./workflows/workflows.component";
import { BroadcastService } from "../../services/broadcast.service";
-import { PlanModel } from "../../model/workflow/plan-model";
+import { PlanModel } from "../../model/plan-model";
@Component({
selector: 'menus',
import { Component, Input, OnChanges, ViewChild } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap/modal';
-import { Microservice } from '../../../../model/workflow/microservice';
-import { WorkflowConfigService } from '../../../../services/workflow-config.service';
import { Swagger } from "../../../../model/swagger";
import { RestConfig } from '../../../../model/rest-config';
+import { RestService } from '../../../../services/rest.service';
/**
* toolbar component contains some basic operations(save) and all of the supported workflow nodes.
public detail: string;
public dynamic = false;
- constructor(private configService: WorkflowConfigService) {
+ constructor(private configService: RestService) {
}
public ngOnChanges() {
}
private loadDynamicInfo() {
- this.configService.loadDynamicInfo(this.microservice.url)
+ this.configService.getDynamicSwaggerInfo(this.microservice.url)
.subscribe(response => {
try {
-
this.microservice.swagger = response;
this.parseSwagger2String();
} catch (e) {
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap/modal';
-import { Microservice } from '../../../../model/workflow/microservice';
import { RestConfig } from '../../../../model/rest-config';
/**
this.onMicroserviceSelected(microservice);
}
- public deleteMicroservice(index: number, microservice: Microservice) {
+ public deleteMicroservice(index: number, microservice: RestConfig) {
this.deleteMicroService(microservice.name, microservice.version);
// set the next microservice selected
import { ModalDirective } from 'ngx-bootstrap/modal';
import { MicroserviceListComponent } from './microservice-list/microservice-list.component';
-import { Microservice } from "../../../model/workflow/microservice";
-import { WorkflowConfigService } from "../../../services/workflow-config.service";
import { RestService } from '../../../services/rest.service';
import { RestConfig } from '../../../model/rest-config';
@ViewChild('microserviceModal') public microserviceModal: ModalDirective;
public microservices: RestConfig[];
- public currentMicroservice: Microservice;
+ public currentMicroservice: RestConfig;
constructor(private restService: RestService) {
}
import { ModalDirective } from 'ngx-bootstrap/modal';\r
\r
import { WorkflowService } from "../../../services/workflow.service";\r
-import { PlanModel } from "../../../model/workflow/plan-model";\r
+import { PlanModel } from "../../../model/plan-model";\r
\r
/**\r
* workflows component\r
</div>
<div class="form-group row">
- <label class="col-md-3 form-control-label text-md-right">Name</label>
+ <label class="col-md-3 form-control-label text-md-right">{{'WORKFLOW.CONNECTION_NAME' | translate}}</label>
<div class="col-md-9">
- <input class="form-control" type="text" [(ngModel)]="sequenceFlow.name">
+ <input class="form-control" type="text" [(ngModel)]="sequenceFlow.name" (ngModelChange)="nameChanged($event)">
</div>
</div>
<div class="form-group row">
- <label class="col-md-3 form-control-label text-md-right">Source</label>
+ <label class="col-md-3 form-control-label text-md-right">{{'WORKFLOW.CONNECTION_SOURCE' | translate}}</label>
<div class="col-md-9">
<input class="form-control" disabled type="text" [(ngModel)]="sequenceFlow.sourceRef">
</div>
</div>
<div class="form-group row">
- <label class="col-md-3 form-control-label text-md-right">Target</label>
+ <label class="col-md-3 form-control-label text-md-right">{{'WORKFLOW.CONNECTION_TARGET' | translate}}</label>
<div class="col-md-9">
<input class="form-control" disabled type="text" [(ngModel)]="sequenceFlow.targetRef">
</div>
</div>
<div class="form-group row">
- <label class="col-md-3 form-control-label text-md-right">Condition</label>
+ <label class="col-md-3 form-control-label text-md-right">{{'WORKFLOW.CONNECTION_CONDITION' | translate}}</label>
<div class="col-md-9">
- <input class="form-control" type="text" [ngModel]="sequenceFlow.condition"
- (ngModelChange)="conditionChanged($event)">
+ <input class="form-control" type="text" [(ngModel)]="sequenceFlow.condition">
</div>
</div>
</div>
public show = false;
constructor(private broadcastService: BroadcastService,
- private processService: ModelService,
+ private modelService: ModelService,
private jsPlumbService: JsPlumbService) {
}
public ngAfterViewInit() {
- this.broadcastService.showSequenceFlow$.subscribe(show => this.show = show);
- this.broadcastService.sequenceFlow$.subscribe(tmp => this.sequenceFlow = tmp);
+ this.broadcastService.showProperty$.subscribe(element => {
+ if (element && !this.modelService.isNode(element)) {
+ this.sequenceFlow = element as SequenceFlow;
+ this.show = true;
+ } else {
+ this.show = false;
+ }
+ });
}
- public conditionChanged(condition: string) {
- this.sequenceFlow.condition = condition;
- this.jsPlumbService.setLabel(this.sequenceFlow.sourceRef, this.sequenceFlow.targetRef, condition);
+ public nameChanged(name: string) {
+ this.sequenceFlow.name = name;
+ this.jsPlumbService.setLabel(this.sequenceFlow.sourceRef, this.sequenceFlow.targetRef, name);
}
public delete() {
this.show = false;
-
- this.processService.deleteConnection(this.sequenceFlow.sourceRef, this.sequenceFlow.targetRef);
+ this.modelService.deleteConnection(this.sequenceFlow.sourceRef, this.sequenceFlow.targetRef);
this.jsPlumbService.deleteConnect(this.sequenceFlow.sourceRef, this.sequenceFlow.targetRef);
}
}
* Contributors:\r
* ZTE - initial API and implementation and/or initial documentation\r
*/\r
+import { WorkflowNode } from './workflow/workflow-node';\r
\r
-import { Injectable } from '@angular/core';\r
-import { WorkflowNode } from "./workflow-node";\r
-import { Configs } from "./configs";\r
-\r
-/**\r
- * PlanModel\r
- */\r
export class PlanModel {\r
public nodes: WorkflowNode[] = [];\r
public configs: any = {};\r
constructor(public name: string,
public value: string,
public children: PlanTreeviewItem[],
- public canSelect?: boolean) {
+ public canSelect = true) {
}
}
-/**\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 { Swagger } from "../swagger";\r
-\r
-/**\r
- * Microservice\r
- */\r
-export class Microservice {\r
- constructor(public name: string, public version: string, public swaggerJson: string, public definition: string) {}\r
-}\r
+/**
+ * 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 { Swagger } from './swagger';
+
+export class SwaggerSetting {
+ constructor(public name: string, public version: string, public url: string, public path: string,
+ public swagger?: Swagger) {
+ }
+}
-/**\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 { Microservice } from "./microservice";\r
-\r
-/**\r
- * Configs\r
- */\r
-export class Configs {\r
- constructor(public microservices:Microservice[]) {}\r
-}\r
+/**
+ * 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 {WorkflowNode} from './workflow-node';
+
+export interface ExclusiveGateway extends WorkflowNode {
+}
* ZTE - initial API and implementation and/or initial documentation\r
*/\r
\r
-import { Injectable } from '@angular/core';\r
-\r
-/**\r
- * Position\r
- * Workflow node position\r
- */\r
export class Position {\r
- constructor(public top: number, public left: number, public width: number = 200, public height: number = 100) { }\r
+ constructor(public left: number, public top: number, public width = 56, public height = 56) { }\r
}\r
* Contributors:
* ZTE - initial API and implementation and/or initial documentation
*/
+import { WorkflowElement } from './workflow-element';
+import { Position } from './position';
-export class SequenceFlow {
-
- constructor(public sourceRef: string, public targetRef: string, public name?: string, public condition?:string) { }
+export interface SequenceFlow extends WorkflowElement {
+ sourceRef: string;
+ // sourcePosition: Position;
+ targetRef: string;
+ // targetPosition: Position;
+ name?: string;
+ condition?: string;
}
import { WorkflowNode } from '../model/workflow/workflow-node';
import { SequenceFlow } from "../model/workflow/sequence-flow";
-import { PlanModel } from "../model/workflow/plan-model";
+import { PlanModel } from "../model/plan-model";
import { WorkflowElement } from '../model/workflow/workflow-element';
import { RestConfig } from '../model/rest-config';
import { WorkflowNode } from "../../model/workflow/workflow-node";\r
import { Observable } from "rxjs/Observable";\r
import { HttpService } from "../../util/http.service";\r
-import { PlanModel } from "../../model/workflow/plan-model";\r
+import { PlanModel } from "../../model/plan-model";\r
\r
/**\r
* CatalogService\r
import { Observable } from "rxjs/Observable";\r
import { WorkflowNode } from "../../model/workflow/workflow-node";\r
import { HttpService } from "../../util/http.service";\r
-import { PlanModel } from "../../model/workflow/plan-model";\r
+import { PlanModel } from "../../model/plan-model";\r
\r
/**\r
* SdcService\r
private selectNodes: WorkflowNode[] = [];\r
\r
constructor(private modelService: ModelService, private broadcastService: BroadcastService) {\r
-\r
this.broadcastService.selectedElement$.subscribe(elements => {\r
this.selectNodes = [];\r
if (elements && 0 < elements.length) {\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/workflow-node";\r
-import { PlanModel } from "../model/workflow/plan-model";\r
-import { Position } from "../model/workflow/position";\r
-import { NodeType } from "../model/workflow/node-type.enum";\r
-import { StartEvent } from "../model/workflow/start-event";\r
-import { SequenceFlow } from "../model/workflow/sequence-flow";\r
-import { RestTask } from "../model/workflow/rest-task";\r
-import { ErrorEvent } from "../model/workflow/error-event";\r
-import { PlanTreeviewItem } from "../model/plan-treeview-item";\r
-import { WorkflowConfigService } from "./workflow-config.service";\r
-import { Swagger, SwaggerModelSimple, SwaggerReferenceObject } from "../model/swagger";\r
-import { WorkflowService } from "./workflow.service";\r
-import { IntermediateCatchEvent } from "../model/workflow/intermediate-catch-event";\r
-import { ScriptTask } from "../model/workflow/script-task";\r
+import { isNullOrUndefined } from 'util';\r
+\r
+import { PlanModel } from '../model/plan-model';\r
+import { PlanTreeviewItem } from '../model/plan-treeview-item';\r
+import { RestConfig } from '../model/rest-config';\r
+import { Swagger, SwaggerModel, SwaggerModelSimple, SwaggerPrimitiveObject, SwaggerReferenceObject } from '../model/swagger';\r
+import { ErrorEvent } from '../model/workflow/error-event';\r
+import { IntermediateCatchEvent } from '../model/workflow/intermediate-catch-event';\r
+import { NodeType } from '../model/workflow/node-type.enum';\r
+import { Parameter } from '../model/workflow/parameter';\r
+import { Position } from '../model/workflow/position';\r
+import { RestTask } from '../model/workflow/rest-task';\r
+import { SequenceFlow } from '../model/workflow/sequence-flow';\r
+import { StartEvent } from '../model/workflow/start-event';\r
+import { SubProcess } from '../model/workflow/sub-process';\r
import { ToscaNodeTask } from '../model/workflow/tosca-node-task';\r
+import { WorkflowNode } from '../model/workflow/workflow-node';\r
import { NodeTemplate } from '../model/topology/node-template';\r
-import { SubProcess } from '../model/workflow/sub-process';\r
-import { TimerEventDefinition, TimerEventDefinitionType } from '../model/workflow/timer-event-definition';\r
-import { Parameter } from '../model/workflow/parameter';\r
import { ValueSource } from '../model/value-source.enum';\r
-import { RestService } from './rest.service';\r
import { BroadcastService } from './broadcast.service';\r
-import { RestConfig } from '../model/rest-config';\r
+import { RestService } from './rest.service';\r
+import { SwaggerTreeConverterService } from './swagger-tree-converter.service';\r
+import { ScriptTask } from "../model/workflow/script-task";\r
+import { TimerEventDefinition, TimerEventDefinitionType } from "../model/workflow/timer-event-definition";\r
\r
/**\r
- * WorkflowService\r
- * provides all of the operations about workflow operations.\r
+ * ModelService\r
+ * provides all operations about plan model.\r
*/\r
@Injectable()\r
export class ModelService {\r
\r
private planModel: PlanModel = new PlanModel();\r
\r
- constructor(private broadcastService: BroadcastService, private restService: RestService, private workflowService: WorkflowService, private configService: WorkflowConfigService) {\r
+ constructor(private broadcastService: BroadcastService, private restService: RestService) {\r
this.broadcastService.planModel$.subscribe(plan => {\r
plan.nodes.forEach(node => {\r
switch (node.type) {\r
});\r
}\r
\r
- public getProcess(): WorkflowNode[] {\r
- return this.workflowService.planModel.nodes;\r
+ public getChildrenNodes(parentId: string): WorkflowNode[] {\r
+ if (!parentId || parentId === this.rootNodeId) {\r
+ return this.planModel.nodes;\r
+ } else {\r
+ const node = this.getNodeMap().get(parentId);\r
+ if (node.type === 'subProcess') {\r
+ return (<SubProcess>node).children;\r
+ } else {\r
+ return [];\r
+ }\r
+ }\r
}\r
\r
public getNodes(): WorkflowNode[] {\r
return this.planModel.nodes;\r
}\r
\r
- public addConnection(sourceId: string, targetId: string) {\r
- const node = this.getNodeMap().get(sourceId);\r
- if (node) {\r
- const index = node.connection.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId);\r
- if (index === -1) {\r
- const sequenceFlow: SequenceFlow = { sourceRef: sourceId, targetRef: targetId };\r
- node.connection.push(sequenceFlow);\r
- }\r
- }\r
- }\r
-\r
- public deleteConnection(sourceId: string, targetId: string) {\r
- const node = this.getNodeMap().get(sourceId);\r
+ public getSequenceFlow(sourceRef: string, targetRef: string): SequenceFlow {\r
+ const node = this.getNodeMap().get(sourceRef);\r
if (node) {\r
- const index = node.connection.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId);\r
- if (index !== -1) {\r
- node.connection.splice(index, 1);\r
- }\r
- }\r
- }\r
-\r
- public deleteNode(parentId: string, nodeId: string): WorkflowNode {\r
- const nodeMap = this.getNodeMap();\r
-\r
- const nodes = this.getChildrenNodes(parentId);\r
-\r
- // delete related connections\r
- nodes.forEach(node => this.deleteConnection(node.id, nodeId));\r
-\r
- // delete current node\r
- const index = nodes.findIndex(node => node.id === nodeId);\r
- if (index !== -1) {\r
- const node = nodes.splice(index, 1)[0];\r
- node.connection = [];\r
- return node;\r
- }\r
-\r
- return null;\r
- }\r
-\r
- public addChild(parentId: string, child: WorkflowNode) {\r
- this.getChildrenNodes(parentId).push(child);\r
- }\r
-\r
- public deleteChild(node: SubProcess, id: string): WorkflowNode {\r
- const index = node.children.findIndex(child => child.id === id);\r
- if (index !== -1) {\r
- const deletedNode = node.children.splice(index, 1);\r
- return deletedNode[0];\r
+ const sequenceFlow = node.connection.find(tmp => tmp.targetRef === targetRef);\r
+ return sequenceFlow;\r
+ } else {\r
+ return null;\r
}\r
-\r
- return null;\r
- }\r
-\r
- public updateRestConfig(restConfigs: RestConfig[]): void {\r
- this.planModel.configs = { restConfigs: restConfigs };\r
- // console.log(this.planModel.configs);\r
- }\r
-\r
- public getNodeMap(): Map<string, WorkflowNode> {\r
- const map = new Map<string, WorkflowNode>();\r
- this.toNodeMap(this.planModel.nodes, map);\r
- return map;\r
- }\r
-\r
- private toNodeMap(nodes: WorkflowNode[], map: Map<string, WorkflowNode>) {\r
- nodes.forEach(node => {\r
- if (node.type === 'subProcess') {\r
- this.toNodeMap((<SubProcess>node).children, map);\r
- }\r
- map.set(node.id, node);\r
- });\r
}\r
\r
public addNode(name: string, type: string, left: number, top: number) {\r
return undefined !== object.type;\r
}\r
\r
- public getSequenceFlow(sourceRef: string, targetRef: string): SequenceFlow {\r
- const node = this.getNodeById(sourceRef);\r
- if (node) {\r
- const sequenceFlow = node.connection.find(tmp => tmp.targetRef === targetRef);\r
- return sequenceFlow;\r
+ // public createNodeByJson(obj: any): WorkflowNode {\r
+ // let node;\r
+ // switch (obj.type) {\r
+ // case NodeType[NodeType.startEvent]:\r
+ // node = new StartEvent(obj.name, obj.id, obj.type, this.rootNodeId, obj.position);\r
+ // node.parameters = obj.parameters;\r
+ // return node;\r
+ // case NodeType[NodeType.restTask]:\r
+ // node = new RestTask(obj.name, obj.id, obj.type, this.rootNodeId, obj.position);\r
+ // node.\r
+ // case NodeType[NodeType.errorStartEvent]:\r
+ // return new ErrorEvent(type, id, type, this.rootNodeId, position);\r
+ // case NodeType[NodeType.errorEndEvent]:\r
+ // return new ErrorEvent(type, id, type, this.rootNodeId, position);\r
+ // case NodeType[NodeType.toscaNodeManagementTask]:\r
+ // return new ToscaNodeTask(type, id, type, this.rootNodeId, position);\r
+ // case NodeType[NodeType.subProcess]:\r
+ // return new SubProcess(type, id, type, this.rootNodeId, position);\r
+ // case NodeType[NodeType.intermediateCatchEvent]:\r
+ // return new IntermediateCatchEvent(type, id, type, this.rootNodeId, position);\r
+ // case NodeType[NodeType.scriptTask]:\r
+ // return new ScriptTask(type, id, type, this.rootNodeId, position);\r
+ // default:\r
+ // return new WorkflowNode(type, id, type, this.rootNodeId, position);\r
+ // }\r
+ // return node;\r
+ // }\r
+\r
+ public changeParent(id: string, originalParentId: string, targetParentId: string) {\r
+ if (originalParentId === targetParentId) {\r
+ return;\r
+ }\r
+\r
+ const node: WorkflowNode = this.deleteNode(originalParentId, id);\r
+ node.parentId = targetParentId;\r
+\r
+ if (targetParentId) {\r
+ this.addChild(targetParentId, node);\r
} else {\r
- return undefined;\r
+ this.planModel.nodes.push(node);\r
}\r
}\r
\r
+ public updatePosition(id: string, left: number, top: number, width: number, height: number) {\r
+ const node = this.getNodeMap().get(id);\r
+ node.position.left = left;\r
+ node.position.top = top;\r
+ node.position.width = width;\r
+ node.position.height = height;\r
+ }\r
+\r
+ public updateRestConfig(restConfigs: RestConfig[]): void {\r
+ this.planModel.configs = { restConfigs: restConfigs };\r
+ // console.log(this.planModel.configs);\r
+ }\r
+\r
+ public getNodeMap(): Map<string, WorkflowNode> {\r
+ const map = new Map<string, WorkflowNode>();\r
+ this.toNodeMap(this.planModel.nodes, map);\r
+ return map;\r
+ }\r
+\r
+ public getAncestors(id: string): WorkflowNode[] {\r
+ const nodeMap = this.getNodeMap();\r
+ const ancestors = [];\r
+\r
+ let ancestor = nodeMap.get(id);\r
+ do {\r
+ ancestor = this.getParentNode(ancestor.id, nodeMap);\r
+ if (ancestor && ancestor.id !== id) {\r
+ ancestors.push(ancestor);\r
+ }\r
+ } while (ancestor);\r
+\r
+ return ancestors;\r
+ }\r
+\r
+ private getParentNode(id: string, nodeMap: Map<string, WorkflowNode>): WorkflowNode {\r
+ let parentNode;\r
+ nodeMap.forEach((node, key) => {\r
+ if (NodeType[NodeType.subProcess] === node.type) {\r
+ const childNode = (<SubProcess>node).children.find(child => child.id === id);\r
+ if (childNode) {\r
+ parentNode = node;\r
+ }\r
+ }\r
+\r
+ });\r
+\r
+ return parentNode;\r
+ }\r
+\r
+ public isDescendantNode(node: WorkflowNode, descendantId: string): boolean {\r
+ if (NodeType[NodeType.subProcess] !== node.type) {\r
+ return false;\r
+ }\r
+ const tmp = (<SubProcess>node).children.find(child => {\r
+ return child.id === descendantId || (NodeType[NodeType.subProcess] === child.type && this.isDescendantNode(<SubProcess>child, descendantId));\r
+ });\r
+\r
+ return tmp !== undefined;\r
+ }\r
+\r
+ private toNodeMap(nodes: WorkflowNode[], map: Map<string, WorkflowNode>) {\r
+ nodes.forEach(node => {\r
+ if (node.type === 'subProcess') {\r
+ this.toNodeMap((<SubProcess>node).children, map);\r
+ }\r
+ map.set(node.id, node);\r
+ });\r
+ }\r
+\r
+ public addConnection(sourceId: string, targetId: string) {\r
+ const node = this.getNodeMap().get(sourceId);\r
+ if (node) {\r
+ const index = node.connection.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId);\r
+ if (index === -1) {\r
+ const sequenceFlow: SequenceFlow = { sourceRef: sourceId, targetRef: targetId };\r
+ node.connection.push(sequenceFlow);\r
+ }\r
+ }\r
+ }\r
+\r
+ public deleteConnection(sourceId: string, targetId: string) {\r
+ const node = this.getNodeMap().get(sourceId);\r
+ if (node) {\r
+ const index = node.connection.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId);\r
+ if (index !== -1) {\r
+ node.connection.splice(index, 1);\r
+ }\r
+ }\r
+ }\r
+\r
+ public deleteNode(parentId: string, nodeId: string): WorkflowNode {\r
+ const nodeMap = this.getNodeMap();\r
+\r
+ const nodes = this.getChildrenNodes(parentId);\r
+\r
+ // delete related connections\r
+ nodes.forEach(node => this.deleteConnection(node.id, nodeId));\r
+\r
+ // delete current node\r
+ const index = nodes.findIndex(node => node.id === nodeId);\r
+ if (index !== -1) {\r
+ const node = nodes.splice(index, 1)[0];\r
+ node.connection = [];\r
+ return node;\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ public addChild(parentId: string, child: WorkflowNode) {\r
+ this.getChildrenNodes(parentId).push(child);\r
+ }\r
+\r
+ public deleteChild(node: SubProcess, id: string): WorkflowNode {\r
+ const index = node.children.findIndex(child => child.id === id);\r
+ if (index !== -1) {\r
+ const deletedNode = node.children.splice(index, 1);\r
+ return deletedNode[0];\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
public getPlanParameters(nodeId: string): PlanTreeviewItem[] {\r
const preNodeList = new Array<WorkflowNode>();\r
- this.getPreNodes(nodeId, preNodeList);\r
+ this.getPreNodes(nodeId, this.getNodeMap(), preNodeList);\r
\r
return this.loadNodeOutputs(preNodeList);\r
}\r
return new PlanTreeviewItem('response', `[${nodeId}].[responseBody]`, []);\r
}\r
\r
- public getPreNodes(nodeId: string, preNodes: WorkflowNode[]) {\r
+ public getPreNodes(nodeId: string, nodeMap: Map<string, WorkflowNode>, preNodes: WorkflowNode[]) {\r
const preNode4CurrentNode = [];\r
- this.getProcess().forEach(node => {\r
+ nodeMap.forEach(node => {\r
if (this.isPreNode(node, nodeId)) {\r
const existNode = preNodes.find(tmpNode => tmpNode.id === node.id);\r
if (existNode) {\r
- // current node already exists in preNodes. this could avoid loop circle.\r
+ // current node already exists. this could avoid loop circle.\r
} else {\r
preNode4CurrentNode.push(node);\r
preNodes.push(node);\r
}\r
});\r
\r
- preNode4CurrentNode.forEach(node => this.getPreNodes(node.id, preNodes));\r
+ preNode4CurrentNode.forEach(node => this.getPreNodes(node.id, nodeMap, preNodes));\r
}\r
\r
public isPreNode(preNode: WorkflowNode, id: string): boolean {\r
return targetNode !== undefined;\r
}\r
\r
- public getNodeById(sourceId: string): WorkflowNode {\r
- return this.getProcess().find(node => node.id === sourceId);\r
+ public save() {\r
+ console.log('****************** save data *********************');\r
+ console.log(this.planModel);\r
+\r
+ this.broadcastService.broadcast(this.broadcastService.saveEvent, this.planModel);\r
}\r
\r
private createId() {\r
\r
return 'node' + nodeMap.size;\r
}\r
-\r
- public getChildrenNodes(parentId: string): WorkflowNode[] {\r
- if (!parentId || parentId === this.rootNodeId) {\r
- return this.planModel.nodes;\r
- } else {\r
- const node = this.getNodeMap().get(parentId);\r
- if (node.type === 'subProcess') {\r
- return (<SubProcess>node).children;\r
- } else {\r
- return [];\r
- }\r
- }\r
- }\r
-\r
- public changeParent(id: string, originalParentId: string, targetParentId: string) {\r
- if (originalParentId === targetParentId) {\r
- return;\r
- }\r
-\r
- const node: WorkflowNode = this.deleteNode(originalParentId, id);\r
- node.parentId = targetParentId;\r
-\r
- if (targetParentId) {\r
- this.addChild(targetParentId, node);\r
- } else {\r
- this.planModel.nodes.push(node);\r
- }\r
- }\r
-\r
- public updatePosition(id: string, left: number, top: number, width: number, height: number) {\r
- const node = this.getNodeMap().get(id);\r
- node.position.left = left;\r
- node.position.top = top;\r
- node.position.width = width;\r
- node.position.height = height;\r
- }\r
-\r
- public isDescendantNode(node: WorkflowNode, descendantId: string): boolean {\r
- if (NodeType[NodeType.subProcess] !== node.type) {\r
- return false;\r
- }\r
- const tmp = (<SubProcess>node).children.find(child => {\r
- return child.id === descendantId || (NodeType[NodeType.subProcess] === child.type && this.isDescendantNode(<SubProcess>child, descendantId));\r
- });\r
-\r
- return tmp !== undefined;\r
- }\r
}\r
import { RestConfig } from '../model/rest-config';\r
import { HttpService } from '../util/http.service';\r
import { BroadcastService } from './broadcast.service';\r
+import { NoticeService } from './notice.service';\r
\r
@Injectable()\r
export class RestService {\r
private runtimeURL = '/openoapi/catalog/v1/sys/config';\r
private msbPublishServiceURL = '/api/msdiscover/v1/publishservicelist';\r
\r
- constructor(private broadcastService: BroadcastService, private http: Http) {\r
+ constructor(private broadcastService: BroadcastService, private http: Http, private noticeService: NoticeService) {\r
this.broadcastService.planModel$.subscribe(planModel => {\r
planModel.configs.restConfigs.forEach(element => {\r
this.restConfigs.push(element);\r
return this.restConfigs;\r
}\r
\r
- // public getDynamicSwaggerInfo(url: string): Observable<any> {\r
- // const options: any = {\r
- // headers: {\r
- // Accept: 'application/json',\r
- // },\r
- // };\r
- // return this.httpService.get(url, options);\r
- // }\r
+ public getDynamicSwaggerInfo(url: string): Observable<any> {\r
+ const options: any = {\r
+ headers: {\r
+ Accept: 'application/json',\r
+ },\r
+ };\r
+ return this.http.get(url, options);\r
+ }\r
\r
public getSwaggerInfo(id: string): Swagger {\r
const restConfig = this.restConfigs.find(tmp => tmp.id === id);\r
import { ValueSource } from '../model/value-source.enum';
import { WorkflowUtil } from '../util/workflow-util';
+import { RestService } from './rest.service';
import { Swagger } from "../model/swagger";
-import { WorkflowConfigService } from "./workflow-config.service";
@Injectable()
export class SwaggerTreeConverterService {
- private swagger: Swagger;
+ private swagger: Swagger;
- constructor(private workflowConfigService: WorkflowConfigService) {
+ constructor(private restService: RestService) {
- }
+ }
- public schema2TreeNode(swagger: Swagger, key: string | number, schema: any, value?: any): any {
- this.swagger = swagger;
- if (schema.$ref) {
- const treeNode = this.getTreeNodeBySwaggerDefinition(key, schema, value);
- return treeNode;
- } else {
- value = this.getInitValue4Param(schema, value);
- return this.parameter2TreeNode(key, schema, value);
- }
+ public schema2TreeNode(swagger: Swagger, key: string | number, schema: any, value?: any): any {
+ this.swagger = swagger;
+ if (schema.$ref) {
+ const treeNode = this.getTreeNodeBySwaggerDefinition(key, schema, value);
+ return treeNode;
+ } else {
+ value = this.getInitValue4Param(schema, value);
+ return this.parameter2TreeNode(key, schema, value);
}
+ }
- private getTreeNodeBySwaggerDefinition(key: string | number, schema: any, value: any): TreeNode {
- const swaggerDefinition = this.workflowConfigService.getDefinition(this.swagger, schema.$ref);
+ private getTreeNodeBySwaggerDefinition(key: string | number, schema: any, value: any): TreeNode {
+ const swaggerDefinition = this.restService.getDefinition(this.swagger, schema.$ref);
- const definitionCopy = WorkflowUtil.deepClone(swaggerDefinition);
+ const definitionCopy = WorkflowUtil.deepClone(swaggerDefinition);
- value = this.getInitValue4Param(definitionCopy, value);
+ value = this.getInitValue4Param(definitionCopy, value);
- return this.schema2TreeNode(this.swagger, key, definitionCopy, value);
- }
+ return this.schema2TreeNode(this.swagger, key, definitionCopy, value);
+ }
- private getInitValue4Param(definition: any, value: any) {
- if (definition.$ref) {
- definition = this.workflowConfigService.getDefinition(this.swagger, definition.$ref);
- }
- if (definition.type === 'object') {
- return this.getInitValue4Object(value);
- } else if (definition.type === 'array') {
- return this.getInitValue4Array(value);
- } else { // primary type
- return this.getInitValue4Primate(value);
- }
+ private getInitValue4Param(definition: any, value: any) {
+ if (definition.$ref) {
+ definition = this.restService.getDefinition(this.swagger, definition.$ref);
}
-
- private getInitValue4Object(value: any) {
- const newValue = {
- value: {},
- valueSource: ValueSource[ValueSource.Definition]
- };
-
- if(!value) {
- return newValue;
- } else {
- if(value.valueSource !== ValueSource[ValueSource.Definition]) {
- return value;
- } else {
- if(!value.value || typeof value.value !== 'object') {
- value.value = {};
- }
- return value;
- }
- }
+ if (definition.type === 'object') {
+ return this.getInitValue4Object(value);
+ } else if (definition.type === 'array') {
+ return this.getInitValue4Array(value);
+ } else { // primary type
+ return this.getInitValue4Primary(value);
}
-
- private getInitValue4Array(value: any) {
- const newValue = {
- value: [],
- valueSource: ValueSource[ValueSource.Definition]
- };
-
- if(!value) {
- return newValue;
+ }
+
+ private getInitValue4Object(value: any) {
+ const newValue = {
+ value: {},
+ valueSource: ValueSource[ValueSource.Definition]
+ };
+
+ if (!value || '' === value) {
+ return newValue;
+ } else {
+ if (value.valueSource !== ValueSource[ValueSource.Definition]) {
+ return value;
} else {
- if(value.valueSource !== ValueSource[ValueSource.Definition]) {
- return value;
- } else {
- if(!(value.value instanceof Array)) {
- value.value = [];
- }
- return value;
+ if (typeof value.value !== 'object') {
+ value.value = {};
}
+ return value;
}
}
-
- private getInitValue4Primate(value: any) {
- const newValue = {
- value: '',
- valueSource: ValueSource[ValueSource.String]
- };
-
- if(!value) {
- return newValue;
+ }
+
+ private getInitValue4Array(value: any) {
+ const newValue = {
+ value: [],
+ valueSource: ValueSource[ValueSource.Definition]
+ };
+
+ if (!value || '' === value) {
+ return newValue;
+ } else {
+ if (value.valueSource !== ValueSource[ValueSource.Definition]) {
+ return value;
} else {
- if(typeof value.value === 'object') {
- value.value = '';
+ if (!(value.value instanceof Array)) {
+ value.value = [];
}
return value;
}
}
+ }
+
+ private getInitValue4Primary(value: any) {
+ const newValue = {
+ value: '',
+ valueSource: ValueSource[ValueSource.String]
+ };
+
+ if (!value) {
+ return newValue;
+ } else {
+ if (typeof value.value === 'object') {
+ value.value = '';
+ }
+ return value;
+ }
+ }
- private parameter2TreeNode(name: string | number, definition: any, value: any): any {
- const nodeType = this.getTreeNodeType(definition);
-
- const node = {
- label: name,
- type: nodeType,
- required: definition.required,
- children: [],
- definition: definition,
- value: value,
- };
-
- if(value.valueSource === ValueSource[ValueSource.Definition]) {
- if (definition.type === 'object') {
- node.children = this.getPropertyFromObject(definition, value.value);
- } else if (definition.type === 'array') {
- this.setChildrenForArray(definition, value.value);
- }
- }
+ private parameter2TreeNode(name: string | number, definition: any, value: any): any {
+ const nodeType = this.getTreeNodeType(definition);
- return node;
- }
+ const node = {
+ label: name,
+ type: nodeType,
+ required: definition.required,
+ children: [],
+ definition: definition,
+ value: value,
+ };
- private getTreeNodeType(param: any): string {
- const type = param.type;
- if (type === 'array') {
- return 'array';
- } else if (type === 'object') {
- if (param.additionalProperties) {
- return 'map';
- } else {
- return 'object';
- }
- } else {
- return 'default';
- }
+ if (value.valueSource === ValueSource[ValueSource.Definition]) {
+ if (definition.type === 'object') {
+ node.children = this.getPropertyFromObject(definition, value.value);
+ } else if (definition.type === 'array') {
+ node.children = this.setChildrenForArray(definition, value.value);
+ }
}
- private setChildrenForArray(definition: any, value: any[]): any[] {
- const children = [];
- value.forEach((itemValue, index) => {
- const itemCopy = WorkflowUtil.deepClone(definition.items);
- children.push(this.schema2TreeNode(this.swagger, index, itemCopy, itemValue));
- });
+ return node;
+ }
- return children;
+ private getTreeNodeType(param: any): string {
+ const type = param.type;
+ if (type === 'array') {
+ return 'array';
+ } else if (type === 'object') {
+ if (param.additionalProperties) {
+ return 'map';
+ } else {
+ return 'object';
+ }
+ } else {
+ return 'default';
+ }
+ }
+
+ private setChildrenForArray(definition: any, value: any[]): any[] {
+ const children = [];
+ value.forEach((itemValue, index) => {
+ const itemCopy = WorkflowUtil.deepClone(definition.items);
+ children.push(this.schema2TreeNode(this.swagger, index, itemCopy, itemValue));
+ });
+
+ return children;
+ }
+
+ private getPropertyFromObject(definition: any, value: any): TreeNode[] {
+ if (definition.properties) {
+ return this.getPropertyFromSimpleObject(definition.properties, value, definition.required);
+ } else if (definition.additionalProperties) {
+ return this.getPropertyFromMapOrDictionary(definition.additionalProperties, value);
+ } else {
+ console.log('getPropertyFromObject() return [], param is:' + JSON.stringify(definition));
+ return [];
}
- private getPropertyFromObject(definition: any, value: any): TreeNode[] {
- if (definition.properties) {
- return this.getPropertyFromSimpleObject(definition.properties, value, definition.required);
- } else if (definition.additionalProperties) {
- return this.getPropertyFromMapOrDictionary(definition.additionalProperties, value);
- } else {
- console.log('getPropertyFromObject() return [], param is:' + JSON.stringify(definition));
- return [];
+ }
+
+ private getPropertyFromSimpleObject(properties: any, objectValue: any, required: string[]): TreeNode[] {
+ const treeNodes: TreeNode[] = [];
+ for (const key in properties) {
+ let property = properties[key];
+ // init required property
+ property.required = false;
+ if (Array.isArray(required)) {
+ for (let index = 0; index < required.length; index++) {
+ if (required[index] === key) {
+ property.required = true;
+ break;
+ }
}
+ }
- }
+ objectValue[key] = this.getInitValue4Param(property, objectValue[key]);
- private getPropertyFromSimpleObject(properties: any, objectValue: any, required: string[]): TreeNode[] {
- const treeNodes: TreeNode[] = [];
- for (const key in properties) {
- let property = properties[key];
- // init required property
- property.required = false;
- if (Array.isArray(required)) {
- for (let index = 0; index < required.length; index++) {
- if (required[index] === key) {
- property.required = true;
- break;
- }
- }
- }
-
- objectValue[key] = this.getInitValue4Param(property, objectValue[key]);
-
- const treeNode = this.schema2TreeNode(this.swagger, key, property, objectValue[key]);
- treeNodes.push(treeNode);
- }
- return treeNodes;
+ const treeNode = this.schema2TreeNode(this.swagger, key, property, objectValue[key]);
+ treeNodes.push(treeNode);
}
+ return treeNodes;
+ }
- private getPropertyFromMapOrDictionary(additionalProperties: any, mapOrDictionary: any): TreeNode[] {
- const treeNodes: TreeNode[] = [];
- for (const key in mapOrDictionary) {
- const propertyCopy = WorkflowUtil.deepClone(additionalProperties);
- propertyCopy.value = mapOrDictionary[key];
+ private getPropertyFromMapOrDictionary(additionalProperties: any, mapOrDictionary: any): TreeNode[] {
+ const treeNodes: TreeNode[] = [];
+ for (const key in mapOrDictionary) {
+ const propertyCopy = WorkflowUtil.deepClone(additionalProperties);
+ propertyCopy.value = mapOrDictionary[key];
- const treeNode = this.schema2TreeNode(this.swagger, key, propertyCopy, propertyCopy.value);
- treeNode.keyEditable = true;
- treeNodes.push(treeNode);
+ const treeNode = this.schema2TreeNode(this.swagger, key, propertyCopy, propertyCopy.value);
+ treeNode.keyEditable = true;
+ treeNodes.push(treeNode);
- if (mapOrDictionary[key] !== propertyCopy.value) {
- mapOrDictionary[key] = propertyCopy.value;
- }
- }
- return treeNodes;
+ if (mapOrDictionary[key] !== propertyCopy.value) {
+ mapOrDictionary[key] = propertyCopy.value;
+ }
}
+ return treeNodes;
+ }
}
+++ /dev/null
-/**\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 { WorkflowService } from "./workflow.service";\r
-import { Microservice } from "../model/workflow/microservice";\r
-import { Observable } from "rxjs/Rx";\r
-import { HttpService } from "../util/http.service";\r
-import { Swagger, SwaggerSchemaObject } from "../model/swagger";\r
-\r
-/**\r
- * WorkflowConfigService\r
- * provides all of the operations about workflow configs.\r
- */\r
-@Injectable()\r
-export class WorkflowConfigService {\r
- constructor(private httpService: HttpService, private workflowService: WorkflowService) {}\r
-\r
- public getMicroservices(): Microservice[] {\r
- return this.workflowService.planModel.configs.microservices;\r
- }\r
-\r
- public loadDynamicInfo(url: string): Observable<any> {\r
- const options: any = {\r
- headers: {\r
- Accept: 'application/json',\r
- },\r
- };\r
- return this.httpService.get(url).map(response => response.data);\r
- }\r
-\r
- public getSwaggerInfo(serviceName: string, version: string): Swagger {\r
- const microservice = this.getMicroservices().find(service => (service.name === serviceName && service.version === version));\r
- if(microservice) {\r
- return new Swagger(JSON.parse(microservice.swaggerJson));\r
- } else {\r
- return undefined;\r
- }\r
- }\r
-\r
- public getDefinition(swagger: Swagger, position: string): SwaggerSchemaObject {\r
- const definitionName = position.substring('#/definitions/'.length);\r
-\r
- return swagger.definitions[definitionName];\r
- }\r
-\r
-}\r
import { Injectable } from '@angular/core';\r
import { DataAccessService } from "./data-access/data-access.service";\r
import { Observable } from "rxjs/Observable";\r
-import { PlanModel } from "../model/workflow/plan-model";\r
-import { Configs } from "../model/workflow/configs";\r
+import { PlanModel } from "../model/plan-model";\r
import { BroadcastService } from "./broadcast.service";\r
\r
/**\r
</head>
<body>
- <script>
- window.__theme = 'bs4';
- </script>
- <app-root></app-root>
+ <!-- Enable bootstrap 4 theme -->
+ <script>window.__theme = 'bs4';</script>
+ <workflow></workflow>
</body>
-
</html>