summaryrefslogtreecommitdiffstats
path: root/sdc-workflow-designer-ui/src/app/services
diff options
context:
space:
mode:
Diffstat (limited to 'sdc-workflow-designer-ui/src/app/services')
-rw-r--r--sdc-workflow-designer-ui/src/app/services/broadcast.service.ts2
-rw-r--r--sdc-workflow-designer-ui/src/app/services/data/in-memory-data.service.ts12
-rw-r--r--sdc-workflow-designer-ui/src/app/services/data/mockdata.ts2
-rw-r--r--sdc-workflow-designer-ui/src/app/services/data/swagger.ts1
-rw-r--r--sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts1135
-rw-r--r--sdc-workflow-designer-ui/src/app/services/model.service.ts1026
-rw-r--r--sdc-workflow-designer-ui/src/app/services/rest.service.ts46
7 files changed, 1126 insertions, 1098 deletions
diff --git a/sdc-workflow-designer-ui/src/app/services/broadcast.service.ts b/sdc-workflow-designer-ui/src/app/services/broadcast.service.ts
index af567b9a..6d80e91e 100644
--- a/sdc-workflow-designer-ui/src/app/services/broadcast.service.ts
+++ b/sdc-workflow-designer-ui/src/app/services/broadcast.service.ts
@@ -81,7 +81,7 @@ export class BroadcastService {
* broadcast datas
* this method will catch the exceptions for the broadcast
* @param subject will broadcast data
- * @param data will be broadcated
+ * @param data will be broadcasted
*/
public broadcast(subject: Subject<any>, data: any) {
try {
diff --git a/sdc-workflow-designer-ui/src/app/services/data/in-memory-data.service.ts b/sdc-workflow-designer-ui/src/app/services/data/in-memory-data.service.ts
index e1ead992..a7449185 100644
--- a/sdc-workflow-designer-ui/src/app/services/data/in-memory-data.service.ts
+++ b/sdc-workflow-designer-ui/src/app/services/data/in-memory-data.service.ts
@@ -31,7 +31,7 @@ export class InMemoryDataService implements InMemoryDbService {
name: 'workflow1',
nodes: [],
configs: {
- microservices: [{
+ restConfigs: [{
definition: "/s/swagger",
name: "test",
swaggerJson: JSON.stringify(swagger),
@@ -47,7 +47,7 @@ export class InMemoryDataService implements InMemoryDbService {
name: 'workflow2',
nodes: [],
configs: {
- microservices: []
+ restConfigs: []
}
},
},
@@ -61,9 +61,11 @@ export class InMemoryDataService implements InMemoryDbService {
const mockobject = {};
const setting = {
- "BackendType":"Catalog"
- }
+ "BackendType":"SDC",
+ };
+
+ const tenant = {tenant: "tenant1"};
- return { workflows, swagger, mockarray,mockobject, setting};
+ return { workflows, swagger, mockarray,mockobject, setting, tenant};
}
}
diff --git a/sdc-workflow-designer-ui/src/app/services/data/mockdata.ts b/sdc-workflow-designer-ui/src/app/services/data/mockdata.ts
index b7f9f90c..ad89e475 100644
--- a/sdc-workflow-designer-ui/src/app/services/data/mockdata.ts
+++ b/sdc-workflow-designer-ui/src/app/services/data/mockdata.ts
@@ -1,4 +1,4 @@
-import {swaggerFjh} from './swagger';
+export const swaggerFjh = {"info":{"version":"1.0.0","contact":{"url":"https://gerrit.onap.org/r/#/admin/projects/vfc/nfvo/lcm","name":"ONAP VFC team","email":"onap-discuss@lists.onap.org"},"description":"VFC Network Service Lifecycle Management Rest API.","title":"ONAP VFC Network Service Lifecycle Management API"},"paths":{"/ns/sfcs/{sfcInstId}":{"delete":{"responses":{"204":{"description":"successful operation","schema":{"$ref":"#/definitions/DeleteResponse"}},"404":{"description":"the sfc instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"required":true,"type":"string","description":"","in":"path","name":"sfcInstId"}],"produces":["application/json"],"tags":["sfc"],"summary":"delete sfc","consumes":["application/json"],"operationId":"delete_sfc"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/SfcInfo"}},"404":{"description":"the sfc instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"description":"sfc instance id","required":true,"type":"string","name":"sfcInstId","in":"path"}],"produces":["application/json"],"tags":["sfc"],"summary":"query the specified sfc info","consumes":["application/json"],"operationId":"query_sfc"}},"/ns/{nsInstanceId}/postdeal":{"post":{"responses":{"202":{"description":""}},"description":"","parameters":[{"required":true,"type":"string","description":"","in":"path","name":"nsInstanceId"},{"schema":{"$ref":"#/definitions/NSInstPostDetailRequest"},"description":"request param","required":true,"name":"body","in":"body"}],"produces":["application/json"],"tags":["postdeal"],"summary":"ns postdeal","consumes":["application/json"],"operationId":"ns_postdeal"}},"/ns/vnfs":{"post":{"responses":{"201":{"description":"","schema":{"$ref":"#/definitions/VnfPostResponse"}}},"description":"","parameters":[{"schema":{"$ref":"#/definitions/VnfPostRequest"},"description":"instantiate request param","required":true,"name":"body","in":"body"}],"produces":["application/json"],"tags":["vnf"],"summary":"vnf create","consumes":["application/json"],"operationId":"create_vnf"}},"/ns/{ns_instance_id}/heal":{"post":{"responses":{"202":{"description":"","schema":{"$ref":"#/definitions/JobInfo"}},"500":{"description":"the url is invalid"}},"parameters":[{"required":true,"type":"string","description":"Identifier of the NS instance.","in":"path","name":"ns_instance_id"},{"schema":{"$ref":"#/definitions/NsHealRequest"},"description":"healVnfData","required":true,"name":"healVnfData","in":"body"}],"tags":["ns"],"description":"ns heal","summary":"ns heal","operationId":"ns_heal"}},"/jobs/{jobId}":{"post":{"responses":{"202":{"description":""}},"parameters":[{"required":true,"type":"string","description":"","in":"path","name":"jobId"},{"schema":{"$ref":"#/definitions/JobProgressRequest"},"description":"request param","required":true,"name":"body","in":"body"}],"tags":["job"],"description":"","summary":"jobstatus","operationId":"post_jobprogress"},"get":{"responses":{"202":{"description":"","schema":{"$ref":"#/definitions/JobDetailInfo"}}},"parameters":[{"required":true,"type":"string","description":"job Id","in":"path","name":"jobId"},{"required":true,"type":"string","description":"job response message id","in":"query","name":"responseId"}],"tags":["job"],"description":"","summary":"jobstatus","operationId":"get_jobstatus"}},"/ns/vls/{vlId}":{"delete":{"responses":{"204":{"description":"successful operation","schema":{"$ref":"#/definitions/DeleteVlResponse"}},"404":{"description":"the vl instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"required":true,"type":"string","description":"","in":"path","name":"vlId"}],"produces":["application/json"],"tags":["vl"],"summary":"delete vl","consumes":["application/json"],"operationId":"delete_vl"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/VlInfo"}},"404":{"description":"the vl instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"description":"vl instance id","required":true,"type":"string","name":"vlId","in":"path"}],"produces":["application/json"],"tags":["vl"],"summary":"query the specified vl info","consumes":["application/json"],"operationId":"query_vl"}},"/ns/vls":{"post":{"responses":{"201":{"description":"","schema":{"$ref":"#/definitions/VlPostResponse"}}},"description":"","parameters":[{"schema":{"$ref":"#/definitions/VlPostRequest"},"description":"instantiate request param","required":true,"name":"body","in":"body"}],"produces":["application/json"],"tags":["vl"],"summary":"vl create","consumes":["application/json"],"operationId":"create_vl"}},"/ns/sfcs":{"post":{"responses":{"201":{"description":"","schema":{"$ref":"#/definitions/SfcPostResponse"}}},"description":"","parameters":[{"schema":{"$ref":"#/definitions/SfcPostRequest"},"description":"request param","required":true,"name":"body","in":"body"}],"produces":["application/json"],"tags":["sfc"],"summary":"sfc create","consumes":["application/json"],"operationId":"create_sfc"}},"/ns/{ns_instance_id}":{"delete":{"responses":{"204":{"description":"The NS instance resource and the associated NS identifier were deleted successfully."}},"parameters":[{"required":true,"type":"string","description":"Identifier of the NS instance.","in":"path","name":"ns_instance_id"}],"tags":["ns"],"description":"ns delete","summary":"ns delete","operationId":"ns_delete"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/NsInstanceInfo"}}},"parameters":[],"tags":["ns"],"description":"ns get","summary":"ns get","operationId":"ns_instance_get"}},"/ns/vnfs/{vnfInstId}":{"delete":{"responses":{"204":{"description":"successful operation","schema":{"$ref":"#/definitions/DeleteResponse"}},"404":{"description":"the vl instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"required":true,"type":"string","description":"","in":"path","name":"vnfInstId"}],"produces":["application/json"],"tags":["vnf"],"summary":"delete vnf","consumes":["application/json"],"operationId":"delete_vnf"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/VnfInfo"}},"404":{"description":"the vnf instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"description":"vnf instance id","required":true,"type":"string","name":"vnfInstId","in":"path"}],"produces":["application/json"],"tags":["vnf"],"summary":"query the specified vnf info","consumes":["application/json"],"operationId":"query_vnf"}},"/ns":{"post":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/NsCreateResponse"}}},"parameters":[{"schema":{"$ref":"#/definitions/NsCreateRequest"},"description":"NS Instance Create Request","required":true,"name":"NSCreateRequest","in":"body"}],"tags":["ns"],"description":"ns create","summary":"ns create","operationId":"ns_create"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/NsInstancesInfo"}}},"parameters":[{"required":true,"type":"string","description":"job response message id","in":"query","name":"csarId"}],"tags":["ns"],"description":"ns get","summary":"ns get","operationId":"ns_instantces_get"}},"/ns/{ns_instance_id}/terminate":{"post":{"responses":{"202":{"description":"","schema":{"$ref":"#/definitions/JobInfo"}},"500":{"description":"the url is invalid"}},"parameters":[{"required":true,"type":"string","description":"Identifier of the NS instance.","in":"path","name":"ns_instance_id"},{"schema":{"$ref":"#/definitions/NsTerminateRequest"},"description":"NsTerminateRequest","required":true,"name":"NsTerminateRequest","in":"body"}],"tags":["ns"],"description":"ns terminate","summary":"ns terminate","operationId":"ns_terminate"}},"/ns/{nsInstanceId}/scale":{"post":{"responses":{"200":{"description":"","schema":{"$ref":"#/definitions/JobInfo"}},"201":{"description":"Invalid Request"}},"parameters":[{"required":true,"type":"string","description":"","in":"path","name":"nsInstanceId"},{"schema":{"$ref":"#/definitions/NsScaleRequest"},"description":"Scale NS Request Body","required":true,"name":"ScaleNSRequest","in":"body"}],"tags":["ns"],"description":"ns scale","summary":"ns scale","operationId":"ns_scale"}},"/mandb/{modelName}":{"delete":{"responses":{"204":{"description":"The tables were deleted successfully."}},"description":"ns table delete","parameters":[{"required":true,"type":"string","description":"model Name.","in":"path","name":"modelName"}],"produces":["application/json"],"tags":["db"],"summary":"ns table delete","consumes":["application/json"],"operationId":"ns_table_delete"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/TableInfo"}},"500":{"description":"the url is invalid"}},"description":"query ns table info","parameters":[{"required":true,"type":"string","description":"model Name.","in":"path","name":"modelName"}],"produces":["application/json"],"tags":["db"],"summary":"query ns table info","consumes":["application/json"],"operationId":"query_ns_table"}},"/ns/{nsInstanceId}/Instantiate":{"post":{"responses":{"200":{"description":"","schema":{"$ref":"#/definitions/JobInfo"}},"201":{"description":"Invalid Request"}},"parameters":[{"required":true,"type":"string","description":"","in":"path","name":"nsInstanceId"},{"schema":{"$ref":"#/definitions/NsInstantiateRequest"},"description":"NS Instantiate Request Body","required":true,"name":"NSInstantiateRequest","in":"body"}],"tags":["ns"],"description":"ns Instantiate","summary":"ns Instantiate","operationId":"ns_Instantiate"}}},"schemes":["http","https"],"produces":["application/json"],"basePath":"/api/nslcm/v1","definitions":{"NsInstanceInfo":{"type":"object","properties":{"nsState":{"type":"string"},"vnfInfo":{"items":{"$ref":"#/definitions/vnfInfo"},"type":"array"},"nsInstanceId":{"type":"string"},"nsdId":{"type":"string"},"vlInfo":{"items":{"$ref":"#/definitions/vlInfo"},"type":"array"},"nsName":{"type":"string"},"vnffgInfo":{"items":{"$ref":"#/definitions/vnffgInfo"},"type":"array"},"description":{"type":"string"}}},"JobDetailInfo":{"type":"object","properties":{"responseDescriptor":{"type":"object","properties":{"status":{"type":"string"},"responseHistoryList":{"items":{"$ref":"#/definitions/jobResponseInfo"},"type":"array"},"responseId":{"type":"string"},"errorCode":{"type":"string"},"progress":{"type":"string"},"statusDescription":{"type":"string"}}},"jobId":{"type":"string"}}},"VnfInfo":{"type":"object","properties":{"vnfInstId":{"type":"string"},"vnfName":{"type":"string"},"vnfStatus":{"type":"string"}}},"DeleteResponse":{"type":"object","properties":{"result":{"enum":[0,1],"type":"integer"},"detail":{"type":"string"}}},"NsHealRequest":{"type":"object","properties":{"vnfInstanceId":{"type":"string"},"cause":{"type":"string"},"additionalParams":{"type":"object","properties":{"action":{"type":"string"},"actionvminfo":{"type":"object","properties":{"vmname":{"type":"string"},"vmid":{"type":"string"}}}}}}},"NsScaleRequest":{"type":"object","properties":{"scaleNsByStepsData":{"$ref":"#/definitions/NsScaleByStepsData"},"scaleType":{"type":"string"}}},"jobResponseInfo":{"type":"object","properties":{"status":{"type":"string"},"progress":{"type":"string"},"responseId":{"type":"string"},"statusDescription":{"type":"string"},"errorCode":{"type":"string"}}},"NSInstPostDetailRequest":{"type":"object","properties":{"status":{"type":"string"}}},"VlInfo":{"type":"object","properties":{"vlId":{"type":"string"},"vlStatus":{"type":"string"},"vlName":{"type":"string"}}},"VnfPostResponse":{"type":"object","properties":{"vnfInstId":{"type":"string"},"jobId":{"type":"string"}}},"NsCreateRequest":{"type":"object","properties":{"nsName":{"type":"string"},"csarId":{"type":"string","description":"the NS package ID"},"description":{"type":"string"}}},"VlPostResponse":{"type":"object","properties":{"vlId":{"type":"string"},"result":{"enum":[0,1],"type":"integer"},"detail":{"type":"string"}}},"SfcPostRequest":{"type":"object","properties":{"sdnControllerId":{"type":"string"},"vnfInstanceData":{"items":{"type":"object"},"type":"array"},"additionalParamForVnf":{"items":{"type":"object"},"type":"array"},"nsInstanceId":{"type":"string"},"jobId":{"type":"string"},"additionalParamForNs":{"items":{"type":"object"},"type":"array"},"context":{"type":"string"},"sapData":{"items":{"type":"object"},"type":"array"},"fpindex":{"type":"string"}}},"NsTerminateRequest":{"type":"object","properties":{"gracefulTerminationTimeout":{"type":"string"},"terminationType":{"type":"string"}}},"JobProgressRequest":{"type":"object","properties":{"progress":{"type":"string"},"errcode":{"type":"string"},"desc":{"type":"string"}}},"SfcInfo":{"type":"object","properties":{"sfcName":{"type":"string"},"sfcInstId":{"type":"string"},"sfcStatus":{"type":"string"}}},"vnfInfo":{"type":"object","properties":{"vnfInstanceId":{"type":"string"},"vnfdId":{"type":"string"},"vnfInstanceName":{"type":"string"}}},"LocationConstraint":{"type":"object","properties":{"locationConstraints":{"type":"object","properties":{"vimid":{"type":"string"}}},"vnfProfileId":{"type":"string"}}},"NsCreateResponse":{"type":"object","properties":{"nsInstanceId":{"type":"string"}}},"VlPostRequest":{"type":"object","properties":{"vnfInstanceData":{"items":{"type":"object"},"type":"array"},"additionalParamForVnf":{"items":{"type":"object"},"type":"array"},"nsInstanceId":{"type":"string"},"flavourId":{"type":"string"},"pnfInfo":{"items":{"type":"object"},"type":"array"},"extNSVirtualLink":{"items":{"type":"object"},"type":"array"},"additionalParamForNs":{"items":{"type":"object"},"type":"array"},"context":{"type":"string"},"sapData":{"items":{"type":"object"},"type":"array"},"nestedNsInstanceId":{"items":{"type":"object"},"type":"array"},"jobId":{"type":"string"},"locationConstraints":{"items":{"type":"object"},"type":"array"},"vlIndex":{"type":"string"}}},"VnfPostRequest":{"type":"object","properties":{"vnfInstanceData":{"items":{"type":"object"},"type":"array"},"vnfIndex":{"type":"string"},"additionalParamForVnf":{"items":{"type":"object"},"type":"array"},"nsInstanceId":{"type":"string"},"flavourId":{"type":"string"},"pnfInfo":{"items":{"type":"object"},"type":"array"},"extNSVirtualLink":{"items":{"type":"object"},"type":"array"},"additionalParamForNs":{"items":{"type":"object"},"type":"array"},"context":{"type":"string"},"sapData":{"items":{"type":"object"},"type":"array"},"nestedNsInstanceId":{"items":{"type":"object"},"type":"array"},"jobId":{"type":"string"},"locationConstraints":{"items":{"type":"object"},"type":"array"}}},"DeleteVlResponse":{"type":"object","properties":{"result":{"enum":[0,1],"type":"integer"},"detail":{"type":"string"}}},"vlInfo":{"type":"object","properties":{"vldId":{"type":"string"},"vlInstanceName":{"type":"string"},"vlInstanceId":{"type":"string"},"relatedCpInstanceId":{"items":{"$ref":"#/definitions/cpInfo"},"type":"array"}}},"cpInfo":{"type":"object","properties":{"cpInstanceId":{"type":"string"},"cpdId":{"type":"string"},"cpInstanceName":{"type":"string"}}},"SfcPostResponse":{"type":"object","properties":{"sfcInstId":{"type":"string"},"jobId":{"type":"string"}}},"NsInstantiateRequest":{"type":"object","properties":{"additionalParamForNs":{"type":"string"},"LocationConstraints":{"items":{"$ref":"#/definitions/LocationConstraint"},"type":"array"}}},"JobInfo":{"type":"object","properties":{"jobId":{"type":"string"}}},"NsInstancesInfo":{"items":{"$ref":"#/definitions/NsInstanceInfo"},"type":"array"},"NsScaleByStepsData":{"type":"object","properties":{"numberOfSteps":{"type":"integer"},"scalingDirection":{"type":"string"},"aspectId":{"type":"string"}}},"vnffgInfo":{"type":"object","properties":{"cpId":{"type":"string"},"virtualLinkId":{"type":"string"},"vnfId":{"type":"string"},"pnfId":{"type":"string"},"nfp":{"type":"string"},"vnffgInstanceId":{"type":"string"}}},"TableInfo":{"type":"object","properties":{"count":{"type":"string"}}}},"swagger":"2.0","consumes":["application/json"]};
export const workflowFJH = {"id":"fjh","name":"fjh","nodes":[{"id":"node0","name":"startEvent","type":"startEvent","position":{"top":31,"left":31,"width":200,"height":100},"connection":[{"sourceRef":"node0","targetRef":"node23"}],"parameters":[{"name":"vlCount","value":"","valueSource":"String","type":"String"},{"name":"vnfCount","value":"","valueSource":"String","type":"String"},{"name":"sfcCount","value":"","valueSource":"String","type":"String"},{"name":"object_context","value":"","valueSource":"String","type":"String"},{"name":"nsInstanceId","value":"","valueSource":"String","type":"String"},{"name":"object_additionalParamForNs","value":"","valueSource":"String","type":"String"},{"name":"object_additionalParamForVnf","value":"","valueSource":"String","type":"String"},{"name":"jobId","value":"","valueSource":"String","type":"String"},{"name":"sdnControllerId","value":"","valueSource":"String","type":"String"},{"name":"templateid","value":"","valueSource":"String","type":"String"},{"name":"instanceid","value":"","valueSource":"String","type":"String"},{"name":"sdnolcmurl","value":"","valueSource":"String","type":"String"},{"name":"statusurl","value":"","valueSource":"String","type":"String"}]},{"id":"node1","name":"endEvent","type":"endEvent","position":{"top":668,"left":955,"width":200,"height":100},"connection":[]},{"id":"node2","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":120,"left":169,"width":200,"height":100},"connection":[{"sourceRef":"node2","targetRef":"node3","condition":"${ vl_index <= vlCount and vl_status='active' }","name":"未完成"},{"sourceRef":"node2","targetRef":"node4","condition":"!( vl_index <= vlCount and vl_status='active' )","name":"创建完成"}]},{"id":"node3","name":"createVL","type":"restTask","position":{"top":213,"left":142,"width":200,"height":100},"connection":[{"sourceRef":"node3","targetRef":"node11"}],"produces":["application/json"],"consumes":["application/json"],"parameters":[{"name":"body","valueSource":"String","type":"String","position":"body","schema":{"$ref":"#/definitions/VlPostRequest"}}],"responses":[{"description":"","schema":{"$ref":"#/definitions/VlPostResponse"}}],"restConfigId":"nslcm","path":"/ns/vls","method":"post"},{"id":"node4","name":"restTask","type":"restTask","position":{"top":115,"left":358,"width":200,"height":100},"connection":[{"sourceRef":"node4","targetRef":"node5"}],"produces":[],"consumes":[],"parameters":[],"responses":[],"restConfigId":"nslcm","path":"","method":""},{"id":"node5","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":212,"left":383,"width":200,"height":100},"connection":[{"sourceRef":"node5","targetRef":"node6","condition":"未完成"},{"sourceRef":"node5","targetRef":"node12","condition":"创建完成"}]},{"id":"node6","name":"createVNF","type":"restTask","position":{"top":306,"left":352,"width":200,"height":100},"connection":[{"sourceRef":"node6","targetRef":"node7"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node7","name":"intermediateCatchEvent","type":"intermediateCatchEvent","position":{"top":558,"left":443,"width":200,"height":100},"connection":[{"sourceRef":"node7","targetRef":"node8"}],"timerEventDefinition":{"type":"timeDuration"}},{"id":"node8","name":"query_vnf nslcm","type":"restTask","position":{"top":639,"left":216,"width":200,"height":100},"connection":[{"sourceRef":"node8","targetRef":"node9"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node9","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":539,"left":264,"width":200,"height":100},"connection":[{"sourceRef":"node9","targetRef":"node7","condition":"未完成"},{"sourceRef":"node9","targetRef":"node10","condition":"已完成"}]},{"id":"node10","name":"scriptTask","type":"scriptTask","position":{"top":303,"left":239,"width":200,"height":100},"connection":[{"sourceRef":"node10","targetRef":"node5"}]},{"id":"node11","name":"scriptTask","type":"scriptTask","position":{"top":207,"left":34,"width":200,"height":100},"connection":[{"sourceRef":"node11","targetRef":"node2"}]},{"id":"node12","name":"restTask","type":"restTask","position":{"top":205,"left":732,"width":200,"height":100},"connection":[{"sourceRef":"node12","targetRef":"node13"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node13","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":287,"left":757,"width":200,"height":100},"connection":[{"sourceRef":"node13","targetRef":"node14","condition":"未结束"},{"sourceRef":"node13","targetRef":"node18","condition":"已结束"}]},{"id":"node14","name":"createSfc","type":"restTask","position":{"top":440,"left":726,"width":200,"height":100},"connection":[{"sourceRef":"node14","targetRef":"node15"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node15","name":"intermediateCatchEvent","type":"intermediateCatchEvent","position":{"top":551,"left":754,"width":200,"height":100},"connection":[{"sourceRef":"node15","targetRef":"node16"}],"timerEventDefinition":{"type":"timeDuration"}},{"id":"node16","name":"restTask","type":"restTask","position":{"top":642,"left":589,"width":200,"height":100},"connection":[{"sourceRef":"node16","targetRef":"node17"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node17","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":551,"left":614,"width":200,"height":100},"connection":[{"sourceRef":"node17","targetRef":"node15","condition":"未结束"},{"sourceRef":"node17","targetRef":"node19","condition":"已结束"}]},{"id":"node18","name":"restTask","type":"restTask","position":{"top":282,"left":927,"width":200,"height":100},"connection":[{"sourceRef":"node18","targetRef":"node20"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node19","name":"scriptTask","type":"scriptTask","position":{"top":275,"left":588,"width":200,"height":100},"connection":[{"sourceRef":"node19","targetRef":"node13"}]},{"id":"node20","name":"Assign_all_status","type":"scriptTask","position":{"top":380,"left":928,"width":200,"height":100},"connection":[{"sourceRef":"node20","targetRef":"node21"}]},{"id":"node21","name":"post_do","type":"restTask","position":{"top":497,"left":929,"width":200,"height":100},"connection":[{"sourceRef":"node21","targetRef":"node22"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node22","name":"jobstatus","type":"restTask","position":{"top":586,"left":927,"width":200,"height":100},"connection":[{"sourceRef":"node22","targetRef":"node1"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node23","name":"scriptTask","type":"scriptTask","position":{"top":16,"left":143,"width":200,"height":100},"connection":[{"sourceRef":"node23","targetRef":"node2"}],"scriptFormate":"javascript","script":"execution.setVariable(\"vl_index\", 1);\nexecution.setVariable(\"vl_status\", \"active\");"}],"configs":{"restConfigs":[{"id": "nslcm", "name":"nslcm","version":"v1","swagger":swaggerFjh,"definition":""}]}};
diff --git a/sdc-workflow-designer-ui/src/app/services/data/swagger.ts b/sdc-workflow-designer-ui/src/app/services/data/swagger.ts
deleted file mode 100644
index 5a9cc939..00000000
--- a/sdc-workflow-designer-ui/src/app/services/data/swagger.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const swaggerFjh = {"info":{"version":"1.0.0","contact":{"url":"https://gerrit.onap.org/r/#/admin/projects/vfc/nfvo/lcm","name":"ONAP VFC team","email":"onap-discuss@lists.onap.org"},"description":"VFC Network Service Lifecycle Management Rest API.","title":"ONAP VFC Network Service Lifecycle Management API"},"paths":{"/ns/sfcs/{sfcInstId}":{"delete":{"responses":{"204":{"description":"successful operation","schema":{"$ref":"#/definitions/DeleteResponse"}},"404":{"description":"the sfc instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"required":true,"type":"string","description":"","in":"path","name":"sfcInstId"}],"produces":["application/json"],"tags":["sfc"],"summary":"delete sfc","consumes":["application/json"],"operationId":"delete_sfc"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/SfcInfo"}},"404":{"description":"the sfc instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"description":"sfc instance id","required":true,"type":"string","name":"sfcInstId","in":"path"}],"produces":["application/json"],"tags":["sfc"],"summary":"query the specified sfc info","consumes":["application/json"],"operationId":"query_sfc"}},"/ns/{nsInstanceId}/postdeal":{"post":{"responses":{"202":{"description":""}},"description":"","parameters":[{"required":true,"type":"string","description":"","in":"path","name":"nsInstanceId"},{"schema":{"$ref":"#/definitions/NSInstPostDetailRequest"},"description":"request param","required":true,"name":"body","in":"body"}],"produces":["application/json"],"tags":["postdeal"],"summary":"ns postdeal","consumes":["application/json"],"operationId":"ns_postdeal"}},"/ns/vnfs":{"post":{"responses":{"201":{"description":"","schema":{"$ref":"#/definitions/VnfPostResponse"}}},"description":"","parameters":[{"schema":{"$ref":"#/definitions/VnfPostRequest"},"description":"instantiate request param","required":true,"name":"body","in":"body"}],"produces":["application/json"],"tags":["vnf"],"summary":"vnf create","consumes":["application/json"],"operationId":"create_vnf"}},"/ns/{ns_instance_id}/heal":{"post":{"responses":{"202":{"description":"","schema":{"$ref":"#/definitions/JobInfo"}},"500":{"description":"the url is invalid"}},"parameters":[{"required":true,"type":"string","description":"Identifier of the NS instance.","in":"path","name":"ns_instance_id"},{"schema":{"$ref":"#/definitions/NsHealRequest"},"description":"healVnfData","required":true,"name":"healVnfData","in":"body"}],"tags":["ns"],"description":"ns heal","summary":"ns heal","operationId":"ns_heal"}},"/jobs/{jobId}":{"post":{"responses":{"202":{"description":""}},"parameters":[{"required":true,"type":"string","description":"","in":"path","name":"jobId"},{"schema":{"$ref":"#/definitions/JobProgressRequest"},"description":"request param","required":true,"name":"body","in":"body"}],"tags":["job"],"description":"","summary":"jobstatus","operationId":"post_jobprogress"},"get":{"responses":{"202":{"description":"","schema":{"$ref":"#/definitions/JobDetailInfo"}}},"parameters":[{"required":true,"type":"string","description":"job Id","in":"path","name":"jobId"},{"required":true,"type":"string","description":"job response message id","in":"query","name":"responseId"}],"tags":["job"],"description":"","summary":"jobstatus","operationId":"get_jobstatus"}},"/ns/vls/{vlId}":{"delete":{"responses":{"204":{"description":"successful operation","schema":{"$ref":"#/definitions/DeleteVlResponse"}},"404":{"description":"the vl instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"required":true,"type":"string","description":"","in":"path","name":"vlId"}],"produces":["application/json"],"tags":["vl"],"summary":"delete vl","consumes":["application/json"],"operationId":"delete_vl"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/VlInfo"}},"404":{"description":"the vl instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"description":"vl instance id","required":true,"type":"string","name":"vlId","in":"path"}],"produces":["application/json"],"tags":["vl"],"summary":"query the specified vl info","consumes":["application/json"],"operationId":"query_vl"}},"/ns/vls":{"post":{"responses":{"201":{"description":"","schema":{"$ref":"#/definitions/VlPostResponse"}}},"description":"","parameters":[{"schema":{"$ref":"#/definitions/VlPostRequest"},"description":"instantiate request param","required":true,"name":"body","in":"body"}],"produces":["application/json"],"tags":["vl"],"summary":"vl create","consumes":["application/json"],"operationId":"create_vl"}},"/ns/sfcs":{"post":{"responses":{"201":{"description":"","schema":{"$ref":"#/definitions/SfcPostResponse"}}},"description":"","parameters":[{"schema":{"$ref":"#/definitions/SfcPostRequest"},"description":"request param","required":true,"name":"body","in":"body"}],"produces":["application/json"],"tags":["sfc"],"summary":"sfc create","consumes":["application/json"],"operationId":"create_sfc"}},"/ns/{ns_instance_id}":{"delete":{"responses":{"204":{"description":"The NS instance resource and the associated NS identifier were deleted successfully."}},"parameters":[{"required":true,"type":"string","description":"Identifier of the NS instance.","in":"path","name":"ns_instance_id"}],"tags":["ns"],"description":"ns delete","summary":"ns delete","operationId":"ns_delete"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/NsInstanceInfo"}}},"parameters":[],"tags":["ns"],"description":"ns get","summary":"ns get","operationId":"ns_instance_get"}},"/ns/vnfs/{vnfInstId}":{"delete":{"responses":{"204":{"description":"successful operation","schema":{"$ref":"#/definitions/DeleteResponse"}},"404":{"description":"the vl instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"required":true,"type":"string","description":"","in":"path","name":"vnfInstId"}],"produces":["application/json"],"tags":["vnf"],"summary":"delete vnf","consumes":["application/json"],"operationId":"delete_vnf"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/VnfInfo"}},"404":{"description":"the vnf instance id is wrong"},"500":{"description":"the url is invalid"}},"description":"","parameters":[{"description":"vnf instance id","required":true,"type":"string","name":"vnfInstId","in":"path"}],"produces":["application/json"],"tags":["vnf"],"summary":"query the specified vnf info","consumes":["application/json"],"operationId":"query_vnf"}},"/ns":{"post":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/NsCreateResponse"}}},"parameters":[{"schema":{"$ref":"#/definitions/NsCreateRequest"},"description":"NS Instance Create Request","required":true,"name":"NSCreateRequest","in":"body"}],"tags":["ns"],"description":"ns create","summary":"ns create","operationId":"ns_create"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/NsInstancesInfo"}}},"parameters":[{"required":true,"type":"string","description":"job response message id","in":"query","name":"csarId"}],"tags":["ns"],"description":"ns get","summary":"ns get","operationId":"ns_instantces_get"}},"/ns/{ns_instance_id}/terminate":{"post":{"responses":{"202":{"description":"","schema":{"$ref":"#/definitions/JobInfo"}},"500":{"description":"the url is invalid"}},"parameters":[{"required":true,"type":"string","description":"Identifier of the NS instance.","in":"path","name":"ns_instance_id"},{"schema":{"$ref":"#/definitions/NsTerminateRequest"},"description":"NsTerminateRequest","required":true,"name":"NsTerminateRequest","in":"body"}],"tags":["ns"],"description":"ns terminate","summary":"ns terminate","operationId":"ns_terminate"}},"/ns/{nsInstanceId}/scale":{"post":{"responses":{"200":{"description":"","schema":{"$ref":"#/definitions/JobInfo"}},"201":{"description":"Invalid Request"}},"parameters":[{"required":true,"type":"string","description":"","in":"path","name":"nsInstanceId"},{"schema":{"$ref":"#/definitions/NsScaleRequest"},"description":"Scale NS Request Body","required":true,"name":"ScaleNSRequest","in":"body"}],"tags":["ns"],"description":"ns scale","summary":"ns scale","operationId":"ns_scale"}},"/mandb/{modelName}":{"delete":{"responses":{"204":{"description":"The tables were deleted successfully."}},"description":"ns table delete","parameters":[{"required":true,"type":"string","description":"model Name.","in":"path","name":"modelName"}],"produces":["application/json"],"tags":["db"],"summary":"ns table delete","consumes":["application/json"],"operationId":"ns_table_delete"},"get":{"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/TableInfo"}},"500":{"description":"the url is invalid"}},"description":"query ns table info","parameters":[{"required":true,"type":"string","description":"model Name.","in":"path","name":"modelName"}],"produces":["application/json"],"tags":["db"],"summary":"query ns table info","consumes":["application/json"],"operationId":"query_ns_table"}},"/ns/{nsInstanceId}/Instantiate":{"post":{"responses":{"200":{"description":"","schema":{"$ref":"#/definitions/JobInfo"}},"201":{"description":"Invalid Request"}},"parameters":[{"required":true,"type":"string","description":"","in":"path","name":"nsInstanceId"},{"schema":{"$ref":"#/definitions/NsInstantiateRequest"},"description":"NS Instantiate Request Body","required":true,"name":"NSInstantiateRequest","in":"body"}],"tags":["ns"],"description":"ns Instantiate","summary":"ns Instantiate","operationId":"ns_Instantiate"}}},"schemes":["http","https"],"produces":["application/json"],"basePath":"/api/nslcm/v1","definitions":{"NsInstanceInfo":{"type":"object","properties":{"nsState":{"type":"string"},"vnfInfo":{"items":{"$ref":"#/definitions/vnfInfo"},"type":"array"},"nsInstanceId":{"type":"string"},"nsdId":{"type":"string"},"vlInfo":{"items":{"$ref":"#/definitions/vlInfo"},"type":"array"},"nsName":{"type":"string"},"vnffgInfo":{"items":{"$ref":"#/definitions/vnffgInfo"},"type":"array"},"description":{"type":"string"}}},"JobDetailInfo":{"type":"object","properties":{"responseDescriptor":{"type":"object","properties":{"status":{"type":"string"},"responseHistoryList":{"items":{"$ref":"#/definitions/jobResponseInfo"},"type":"array"},"responseId":{"type":"string"},"errorCode":{"type":"string"},"progress":{"type":"string"},"statusDescription":{"type":"string"}}},"jobId":{"type":"string"}}},"VnfInfo":{"type":"object","properties":{"vnfInstId":{"type":"string"},"vnfName":{"type":"string"},"vnfStatus":{"type":"string"}}},"DeleteResponse":{"type":"object","properties":{"result":{"enum":[0,1],"type":"integer"},"detail":{"type":"string"}}},"NsHealRequest":{"type":"object","properties":{"vnfInstanceId":{"type":"string"},"cause":{"type":"string"},"additionalParams":{"type":"object","properties":{"action":{"type":"string"},"actionvminfo":{"type":"object","properties":{"vmname":{"type":"string"},"vmid":{"type":"string"}}}}}}},"NsScaleRequest":{"type":"object","properties":{"scaleNsByStepsData":{"$ref":"#/definitions/NsScaleByStepsData"},"scaleType":{"type":"string"}}},"jobResponseInfo":{"type":"object","properties":{"status":{"type":"string"},"progress":{"type":"string"},"responseId":{"type":"string"},"statusDescription":{"type":"string"},"errorCode":{"type":"string"}}},"NSInstPostDetailRequest":{"type":"object","properties":{"status":{"type":"string"}}},"VlInfo":{"type":"object","properties":{"vlId":{"type":"string"},"vlStatus":{"type":"string"},"vlName":{"type":"string"}}},"VnfPostResponse":{"type":"object","properties":{"vnfInstId":{"type":"string"},"jobId":{"type":"string"}}},"NsCreateRequest":{"type":"object","properties":{"nsName":{"type":"string"},"csarId":{"type":"string","description":"the NS package ID"},"description":{"type":"string"}}},"VlPostResponse":{"type":"object","properties":{"vlId":{"type":"string"},"result":{"enum":[0,1],"type":"integer"},"detail":{"type":"string"}}},"SfcPostRequest":{"type":"object","properties":{"sdnControllerId":{"type":"string"},"vnfInstanceData":{"items":{"type":"object"},"type":"array"},"additionalParamForVnf":{"items":{"type":"object"},"type":"array"},"nsInstanceId":{"type":"string"},"jobId":{"type":"string"},"additionalParamForNs":{"items":{"type":"object"},"type":"array"},"context":{"type":"string"},"sapData":{"items":{"type":"object"},"type":"array"},"fpindex":{"type":"string"}}},"NsTerminateRequest":{"type":"object","properties":{"gracefulTerminationTimeout":{"type":"string"},"terminationType":{"type":"string"}}},"JobProgressRequest":{"type":"object","properties":{"progress":{"type":"string"},"errcode":{"type":"string"},"desc":{"type":"string"}}},"SfcInfo":{"type":"object","properties":{"sfcName":{"type":"string"},"sfcInstId":{"type":"string"},"sfcStatus":{"type":"string"}}},"vnfInfo":{"type":"object","properties":{"vnfInstanceId":{"type":"string"},"vnfdId":{"type":"string"},"vnfInstanceName":{"type":"string"}}},"LocationConstraint":{"type":"object","properties":{"locationConstraints":{"type":"object","properties":{"vimid":{"type":"string"}}},"vnfProfileId":{"type":"string"}}},"NsCreateResponse":{"type":"object","properties":{"nsInstanceId":{"type":"string"}}},"VlPostRequest":{"type":"object","properties":{"vnfInstanceData":{"items":{"type":"object"},"type":"array"},"additionalParamForVnf":{"items":{"type":"object"},"type":"array"},"nsInstanceId":{"type":"string"},"flavourId":{"type":"string"},"pnfInfo":{"items":{"type":"object"},"type":"array"},"extNSVirtualLink":{"items":{"type":"object"},"type":"array"},"additionalParamForNs":{"items":{"type":"object"},"type":"array"},"context":{"type":"string"},"sapData":{"items":{"type":"object"},"type":"array"},"nestedNsInstanceId":{"items":{"type":"object"},"type":"array"},"jobId":{"type":"string"},"locationConstraints":{"items":{"type":"object"},"type":"array"},"vlIndex":{"type":"string"}}},"VnfPostRequest":{"type":"object","properties":{"vnfInstanceData":{"items":{"type":"object"},"type":"array"},"vnfIndex":{"type":"string"},"additionalParamForVnf":{"items":{"type":"object"},"type":"array"},"nsInstanceId":{"type":"string"},"flavourId":{"type":"string"},"pnfInfo":{"items":{"type":"object"},"type":"array"},"extNSVirtualLink":{"items":{"type":"object"},"type":"array"},"additionalParamForNs":{"items":{"type":"object"},"type":"array"},"context":{"type":"string"},"sapData":{"items":{"type":"object"},"type":"array"},"nestedNsInstanceId":{"items":{"type":"object"},"type":"array"},"jobId":{"type":"string"},"locationConstraints":{"items":{"type":"object"},"type":"array"}}},"DeleteVlResponse":{"type":"object","properties":{"result":{"enum":[0,1],"type":"integer"},"detail":{"type":"string"}}},"vlInfo":{"type":"object","properties":{"vldId":{"type":"string"},"vlInstanceName":{"type":"string"},"vlInstanceId":{"type":"string"},"relatedCpInstanceId":{"items":{"$ref":"#/definitions/cpInfo"},"type":"array"}}},"cpInfo":{"type":"object","properties":{"cpInstanceId":{"type":"string"},"cpdId":{"type":"string"},"cpInstanceName":{"type":"string"}}},"SfcPostResponse":{"type":"object","properties":{"sfcInstId":{"type":"string"},"jobId":{"type":"string"}}},"NsInstantiateRequest":{"type":"object","properties":{"additionalParamForNs":{"type":"string"},"LocationConstraints":{"items":{"$ref":"#/definitions/LocationConstraint"},"type":"array"}}},"JobInfo":{"type":"object","properties":{"jobId":{"type":"string"}}},"NsInstancesInfo":{"items":{"$ref":"#/definitions/NsInstanceInfo"},"type":"array"},"NsScaleByStepsData":{"type":"object","properties":{"numberOfSteps":{"type":"integer"},"scalingDirection":{"type":"string"},"aspectId":{"type":"string"}}},"vnffgInfo":{"type":"object","properties":{"cpId":{"type":"string"},"virtualLinkId":{"type":"string"},"vnfId":{"type":"string"},"pnfId":{"type":"string"},"nfp":{"type":"string"},"vnffgInstanceId":{"type":"string"}}},"TableInfo":{"type":"object","properties":{"count":{"type":"string"}}}},"swagger":"2.0","consumes":["application/json"]};
diff --git a/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts b/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts
index c6cf60a8..e90efa7e 100644
--- a/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts
+++ b/sdc-workflow-designer-ui/src/app/services/jsplumb.service.ts
@@ -1,562 +1,573 @@
-/**
- * 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';
-
-import { Subscription } from 'rxjs/Subscription';
-import { WorkflowNode } from '../model/workflow/workflow-node';
-import { BroadcastService } from './broadcast.service';
-import { ModelService } from './model.service';
-import { SequenceFlow } from '../model/workflow/sequence-flow';
-import { Position } from '../model/workflow/position';
-
-/**
- * JsPlumbService
- * provides all of the operations about jsplumb plugin.
- */
-@Injectable()
-export class JsPlumbService {
- public jsplumbInstanceMap = new Map<string, any>();
- public subscriptionMap = new Map<string, Subscription>();
-
- private padding = 20;
- private rootClass = 'canvas';
- private selectNodes: WorkflowNode[] = [];
-
- constructor(private modelService: ModelService, private broadcastService: BroadcastService) {
- this.broadcastService.selectedElement$.subscribe(elements => {
- this.selectNodes = [];
- if (elements && 0 < elements.length) {
- for (let index = 0; index < elements.length; index++) {
- let element = elements[index];
- if (this.modelService.isNode(element)) {
- let node = element as WorkflowNode;
- this.selectNodes.push(node);
- }
- }
- }
- });
- }
-
- public connectChildrenNodes(parentNodeId: string) {
- const jsplumbInstance = this.jsplumbInstanceMap.get(parentNodeId);
-
- const nodes: WorkflowNode[] = this.modelService.getChildrenNodes(parentNodeId);
- nodes.forEach(node => this.connect4OneNode(node, jsplumbInstance));
- }
-
- public connect4OneNode(node: WorkflowNode, jsplumbInstance: any) {
- node.connection.forEach(sequenceFlow => {
- const connection = jsplumbInstance.connect({
- source: sequenceFlow.sourceRef,
- target: sequenceFlow.targetRef,
- });
- if (sequenceFlow.name) {
- connection.setLabel(sequenceFlow.name);
- }
- });
- }
-
- public initJsPlumbInstance(id: string) {
- if (this.jsplumbInstanceMap.get(id)) {
- return;
- }
- const jsplumbInstance = jsp.jsPlumb.getInstance();
-
- jsplumbInstance.importDefaults({
- Anchor: "Continuous",
- Endpoint: "Blank",
- Container: "pallete",
- ReattachConnections: true,
- Connector: ['Flowchart', {
- stub: [0, 0],
- cornerRadius: 5,
- alwaysRespectStubs: true
- }],
- PaintStyle: {
- stroke: "#7D8695",
- strokeWidth: 1,
- radius: 1,
- outlineStroke: "transform",
- outlineWidth: 4
- },
- ConnectorStyle: {
- stroke: "#7D8695",
- strokeWidth: 1,
- outlineStroke: "transform",
- outlineWidth: 4
- },
- ConnectorHoverStyle: {
- stroke: "#00ABFF",
- strokeWidth: 2,
- outlineStroke: "transform",
- outlineWidth: 4
- },
- ConnectionOverlays: [
- ['Arrow', {
- location: 1,
- id: 'arrow',
- cssClass: 'icon-port',
- width: 11,
- length: 12
- }],
- ['Label', { label: '', id: 'label' }]
- ]
- });
-
- // add connection to model data while a new connection is build
- jsplumbInstance.bind('connection', info => {
- this.modelService.addConnection(info.connection.sourceId, info.connection.targetId);
-
- this.subscribe4Connection(info.connection);
-
- info.connection.bind('click', (connection, event) => {
- if ('Label' === connection.type) {
- return;
- }
- event.stopPropagation();
- const sequenceFlow = this.modelService.getSequenceFlow(connection.sourceId, connection.targetId);
- this.broadcastService.broadcast(this.broadcastService.showProperty, null);
- this.broadcastService.broadcast(this.broadcastService.selectedElement, [sequenceFlow]);
- });
-
- info.connection.bind('dblclick', connection => {
- if ('Label' === connection.type) {
- return;
- }
- const sequenceFlow = this.modelService.getSequenceFlow(connection.sourceId, connection.targetId);
- this.broadcastService.broadcast(this.broadcastService.showProperty, sequenceFlow);
- });
- });
-
- this.jsplumbInstanceMap.set(id, jsplumbInstance);
- }
-
- private subscribe4Connection(connection: any) {
- const pre = connection.sourceId + connection.targetId;
- let sequenceFlowSubscription = this.subscriptionMap.get(pre + 'sequenceFlowSubscription');
- if (sequenceFlowSubscription && !sequenceFlowSubscription.closed) {
- sequenceFlowSubscription.unsubscribe();
- }
-
- let currentThis = this;
- sequenceFlowSubscription = this.broadcastService.selectedElement$.subscribe(elements => {
- let selected = false;
- if (elements && 0 < elements.length) {
- for (let index = 0; index < elements.length; index++) {
- let element = elements[index];
- if (!this.modelService.isNode(element)) {
- let sequence = element as SequenceFlow;
- if (sequence.sourceRef === connection.sourceId
- && sequence.targetRef === connection.targetId) {
- selected = true;
- }
- }
- }
- }
- if (selected) {
- connection.setPaintStyle({
- stroke: '#00ABFF',
- strokeWidth: 1,
- radius: 1,
- outlineStroke: "transform",
- outlineWidth: 4
- });
- } else {
- connection.setPaintStyle({
- stroke: '#7D8695',
- strokeWidth: 1,
- radius: 1,
- outlineStroke: "transform",
- outlineWidth: 4
- });
- }
- });
- this.subscriptionMap.set(pre + 'sequenceFlowSubscription', sequenceFlowSubscription);
- }
-
- private unsubscription4Connection(connectionSelection: any) {
- connectionSelection.each(connection => {
- const pre = connection.sourceId + connection.targetId;
- this.subscriptionMap.get(pre + 'sequenceFlowSubscription').unsubscribe();
- });
- }
-
- public deleteConnect(sourceId: string, targetId: string) {
- const sourceNode = this.modelService.getNodeMap().get(sourceId);
- const jsplumbInstance = this.jsplumbInstanceMap.get(sourceNode.parentId);
- const connectionSelection = jsplumbInstance.select({ source: sourceId, target: targetId });
- this.unsubscription4Connection(connectionSelection);
- connectionSelection.delete();
- }
-
- public setLabel(sourceId: string, targetId: string, label: string) {
- const sourceNode = this.modelService.getNodeMap().get(sourceId);
- const jsplumbInstance = this.jsplumbInstanceMap.get(sourceNode.parentId);
- const connections = jsplumbInstance.select({ source: sourceId, target: targetId });
- connections.setLabel(label);
- }
-
- public getParentNodeId(id: string): string {
- const nodeElement = jsp.jsPlumb.getSelector('#' + id);
- const parentNode = this.getParentNodeEl(nodeElement[0]);
-
- return parentNode ? parentNode.id : null;
- }
-
- public initNode(node: WorkflowNode) {
- const jsplumbInstance = this.jsplumbInstanceMap.get(node.parentId);
-
- this.jsplumbInstanceMap.get(this.modelService.rootNodeId).draggable(node.id, {
- scope: 'node',
- filter: '.ui-resizable-handle',
- classes: {
- 'ui-draggable': 'dragging'
- },
- // grid: [5, 5],
- drag: event => {
- // out of container edge, reset to minimal value.
- if (0 > event.pos[0]) {
- event.el.style.left = '0px';
- }
- if (0 > event.pos[1]) {
- event.el.style.top = '0px';
- }
-
- if (0 < this.selectNodes.length) {
- let moveAll = false;
- this.selectNodes.forEach(element => {
- if (element.id === event.el.id) {
- moveAll = true;
- }
- });
- if (moveAll) {
- this.selectNodes.forEach(selectNode => {
- if (selectNode.id !== event.el.id) {
- selectNode.position.left += event.e.movementX;
- selectNode.position.left = 0 > selectNode.position.left ? 0 : selectNode.position.left;
- selectNode.position.top += event.e.movementY;
- selectNode.position.top = 0 > selectNode.position.top ? 0 : selectNode.position.top;
- }
- jsplumbInstance.revalidate(jsplumbInstance.getSelector('#' + selectNode.id));
- });
- }
- }
- },
- stop: event => {
- this.selectNodes.forEach(selectNode => {
- jsplumbInstance.revalidate(jsplumbInstance.getSelector('#' + selectNode.id));
- });
- }
- });
-
- jsplumbInstance.makeTarget(node.id, {
- maxConnections: -1,
- beforeDrop: function (info) {
- const sourceId = info.sourceId;
- const targetId = info.targetId;
- if (sourceId === targetId) {
- return false;
- }
- const sameConnections = this.instance.getConnections({ source: sourceId, target: targetId });
- if (sameConnections && 0 < sameConnections.length) {
- return false;
- }
- return true;
- }
-
- });
-
- jsplumbInstance.makeSource(node.id, {
- filter: '.anchor, .anchor *',
- maxConnections: -1,
- });
- }
-
- public nodeDroppable(node: WorkflowNode, rank: number) {
- const jsplumbInstance = this.jsplumbInstanceMap.get(node.parentId);
-
- const selector = jsplumbInstance.getSelector('#' + node.id);
- this.jsplumbInstanceMap.get(this.modelService.rootNodeId).droppable(selector, {
- scope: 'node',
- rank,
- tolerance: 'pointer',
- drop: event => {
- if (!this.isChildNode(event.drop.el, event.drag.el)) {
- this.drop(event);
- }
- return true;
- },
- canDrop: drag => {
- const nodeMap = this.modelService.getNodeMap();
- const ancestorNode = nodeMap.get(drag.el.id);
-
- const isAncestor = this.modelService.isDescendantNode(ancestorNode, node.id);
- return !isAncestor;
- },
- });
- }
-
- private isChildNode(childElement, parentElement) {
- while (childElement !== parentElement) {
- childElement = childElement.parentNode;
- if (childElement.classList.contains('canvas')) {
- return false;
- }
- }
-
- return true;
- }
-
- private drop(event) {
- const dragEl = event.drag.el;
- const dropEl = event.drop.el;
-
- this.resizeParent(dragEl, dropEl);
-
- const nodeLeft = dragEl.getBoundingClientRect().left;
- const nodeTop = dragEl.getBoundingClientRect().top;
- const parentLeft = dropEl.getBoundingClientRect().left;
- const parentTop = dropEl.getBoundingClientRect().top;
- const left = nodeLeft - parentLeft + dropEl.scrollLeft;
- const top = nodeTop - parentTop + dropEl.scrollTop;
- dragEl.style.top = top + 'px';
- dragEl.style.left = left + 'px';
-
- // 12 is title height
- this.modelService.updatePosition(dragEl.id, left, top, dragEl.getBoundingClientRect().width, dragEl.getBoundingClientRect().height - 12);
-
- const originalParentNode = this.getParentNodeEl(dragEl);
- const originalParentNodeId = originalParentNode ? originalParentNode.id : this.modelService.rootNodeId;
-
- const targetParentNodeId = dropEl.classList.contains('node') ? dropEl.id : this.modelService.rootNodeId;
- this.changeParent(dragEl.id, originalParentNodeId, targetParentNodeId);
- }
-
- private changeParent(id: string, originalParentNodeId: string, targetParentNodeId: string) {
- if (originalParentNodeId !== targetParentNodeId) {
- this.jsplumbInstanceMap.get(originalParentNodeId).removeAllEndpoints(id);
- this.modelService.changeParent(id, originalParentNodeId, targetParentNodeId);
- }
- }
-
- private getParentNodeEl(element) {
- while (!(element.parentNode.classList.contains('node') || element.parentNode.classList.contains('canvas'))) {
- element = element.parentNode;
- }
-
- if (element.parentNode.classList.contains('canvas')) { // top level node
- return null;
- } else {
- return element.parentNode;
- }
- }
-
- public canvasDroppable() {
- const jsplumbInstance = this.jsplumbInstanceMap.get(this.modelService.rootNodeId);
- const canvasSelector = jsplumbInstance.getSelector('.canvas');
- jsplumbInstance.droppable(canvasSelector, {
- scope: 'node',
- rank: 0,
- grid: [5, 5],
- drop: event => this.drop(event),
- });
- }
-
- public buttonDraggable() {
- const jsplumbInstance = this.jsplumbInstanceMap.get(this.modelService.rootNodeId);
- const selector = jsplumbInstance.getSelector('.item');
- jsplumbInstance.draggable(selector, {
- scope: 'btn',
- clone: true
- });
- }
-
- public buttonDroppable() {
- const jsplumbInstance = this.jsplumbInstanceMap.get(this.modelService.rootNodeId);
- const selector = jsplumbInstance.getSelector('.canvas');
- jsplumbInstance.droppable(selector, {
- scope: 'btn',
- // grid: [5, 5],
- drop: event => {
- const el = jsplumbInstance.getSelector(event.drag.el);
- const type = el.attributes.nodeType.value;
- // Mouse position minus drop canvas start position plus scroll position.
- let left = event.e.x - event.drop.pagePosition[0] + event.drop.el.scrollLeft;
- let top = event.e.y - event.drop.pagePosition[1] + event.drop.el.scrollTop;
- if (0 > left) {
- left = 0;
- }
- if (0 > top) {
- top = 0;
- }
- const name = event.drag.el.children[1].innerText;
- this.modelService.addNode(name, type, left, top);
- },
- });
- }
-
- public remove(node: WorkflowNode) {
- const jsplumbInstance = this.jsplumbInstanceMap.get(node.parentId);
-
- // unsubscription4Connection
- const connectionsAsSource = jsplumbInstance.select({ source: node.id });
- this.unsubscription4Connection(connectionsAsSource);
- const connectionsAsTarget = jsplumbInstance.select({ target: node.id });
- this.unsubscription4Connection(connectionsAsTarget);
-
- jsplumbInstance.remove(node.id);
- }
-
- public resizeParent(element: any, parentElement: any) {
- if (parentElement.classList.contains(this.rootClass)) {
- return;
- }
-
- if (!parentElement.classList.contains('node')) {
- this.resizeParent(element, parentElement.parentNode);
- return;
- }
-
- const leftResized = this.resizeParentLeft(element, parentElement);
- const rightResized = this.resizeParentRight(element, parentElement);
- const topResized = this.resizeParentTop(element, parentElement);
- const bottomResized = this.resizeParentBottom(element, parentElement);
-
- if (leftResized || rightResized || topResized || bottomResized) {
- if (parentElement.classList.contains('node')) {
- const rect = parentElement.getBoundingClientRect();
- this.modelService.updatePosition(parentElement.id,
- parentElement.offsetLeft,
- parentElement.offsetTop,
- // title height
- rect.width, rect.height - 12);
- }
- this.resizeParent(parentElement, parentElement.parentNode);
- }
- }
-
- private resizeParentLeft(element: any, parentElement: any): boolean {
- let resized = false;
-
- const actualLeft = element.getBoundingClientRect().left;
- const actualParentLeft = parentElement.getBoundingClientRect().left;
-
- if (actualLeft - this.padding < actualParentLeft) {
- const width = actualParentLeft - actualLeft + this.padding;
-
- this.translateElement(parentElement, -width, 0, width, 0);
- this.translateChildren(parentElement, element, width, 0);
- resized = true;
- }
-
- return resized;
- }
-
- private resizeParentRight(element: any, parentElement: any): boolean {
- let resized = false;
-
- const actualLeft = element.getBoundingClientRect().left;
- const actualRight = actualLeft + element.offsetWidth;
-
- const actualParentLeft = parentElement.getBoundingClientRect().left;
-
- if ((actualParentLeft + parentElement.offsetWidth) < actualRight + this.padding) {
- this.setElementWidth(parentElement, actualRight + this.padding - actualParentLeft);
- resized = true;
- }
-
- return resized;
- }
-
- private resizeParentBottom(element: any, parentElement: any): boolean {
- let resized = false;
-
- const actualTop = element.getBoundingClientRect().top;
- const actualBottom = actualTop + element.offsetHeight;
-
- const actualParentTop = parentElement.getBoundingClientRect().top;
- const actualParentBottom = actualParentTop + parentElement.offsetHeight;
-
- if (actualParentBottom < actualBottom + this.padding) {
- this.setElementHeight(parentElement, actualBottom + this.padding - actualParentTop);
- resized = true;
- }
-
- return resized;
- }
-
- private resizeParentTop(element: any, parentElement: any): boolean {
- let resized = false;
-
- const actualTop = element.getBoundingClientRect().top;
- const actualParentTop = parentElement.getBoundingClientRect().top;
-
- if (actualTop - this.padding < actualParentTop) {
- const height = actualParentTop - actualTop + this.padding;
-
- this.translateElement(parentElement, 0, -height, 0, height);
- this.translateChildren(parentElement, element, 0, height);
- resized = true;
- }
-
- return resized;
- }
-
- private translateElement(element, left: number, top: number, width: number, height: number) {
- const offsetLeft = element.offsetLeft + left;
- element.style.left = offsetLeft + 'px';
-
- const offsetTop = element.offsetTop + top;
- element.style.top = offsetTop + 'px';
-
- const offsetWidth = element.offsetWidth + width;
- element.style.width = offsetWidth + 'px';
-
- const offsetHeight = element.offsetHeight + height;
- element.style.height = offsetHeight + 'px';
-
- if (element.classList.contains('node')) {
- const node = this.modelService.getNodeMap().get(element.id);
- this.jsplumbInstanceMap.get(node.parentId).revalidate(element.id);
- }
- }
-
- private translateChildren(parentElment, excludeElement, left: number, top: number) {
- const len = parentElment.children.length;
- for (let i = 0; i < len; i++) {
- const childElment = parentElment.children[i];
- if (childElment.localName === 'b4t-node') {
- this.translateElement(childElment.children[0], left, top, 0, 0);
- }
- }
- }
-
- private setElementHeight(element, height: number) {
- element.style.height = height + 'px';
- }
-
- private setElementWidth(element, width: number) {
- element.style.width = width + 'px';
- }
-
- private getActualPosition(element, offset: string) {
- let actualPosition = element[offset];
- let current = element.offsetParent;
- while (current !== null) {
- actualPosition += element[offset];
- current = current.offsetParent;
- }
- return actualPosition;
- }
-}
+/**
+ * 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';
+
+import { Subscription } from 'rxjs/Subscription';
+import { WorkflowNode } from '../model/workflow/workflow-node';
+import { BroadcastService } from './broadcast.service';
+import { ModelService } from './model.service';
+import { SequenceFlow } from '../model/workflow/sequence-flow';
+import { Position } from '../model/workflow/position';
+
+/**
+ * JsPlumbService
+ * provides all of the operations about jsplumb plugin.
+ */
+@Injectable()
+export class JsPlumbService {
+ public jsplumbInstanceMap = new Map<string, any>();
+ public subscriptionMap = new Map<string, Subscription>();
+
+ private padding = 20;
+ private rootClass = 'canvas';
+ private selectNodes: WorkflowNode[] = [];
+
+ constructor(private modelService: ModelService, private broadcastService: BroadcastService) {
+ this.broadcastService.selectedElement$.subscribe(elements => {
+ this.selectNodes = [];
+ if (elements && 0 < elements.length) {
+ for (let index = 0; index < elements.length; index++) {
+ let element = elements[index];
+ if (this.modelService.isNode(element)) {
+ let node = element as WorkflowNode;
+ this.selectNodes.push(node);
+ }
+ }
+ }
+ });
+
+ this.broadcastService.planModel$.subscribe(Workflow => {
+ this.jsplumbInstanceMap.get(this.modelService.rootNodeId).reset();
+ this.unsubscriptionAll();
+ this.buttonDraggable();
+ this.buttonDroppable();
+ });
+ }
+
+ private unsubscriptionAll() {
+ this.subscriptionMap.forEach(subscription => subscription.unsubscribe());
+ }
+
+ public connectChildrenNodes(parentNodeId: string) {
+ const jsplumbInstance = this.jsplumbInstanceMap.get(parentNodeId);
+
+ const nodes: WorkflowNode[] = this.modelService.getChildrenNodes(parentNodeId);
+ nodes.forEach(node => this.connect4OneNode(node, jsplumbInstance));
+ }
+
+ public connect4OneNode(node: WorkflowNode, jsplumbInstance: any) {
+ node.connection.forEach(sequenceFlow => {
+ const connection = jsplumbInstance.connect({
+ source: sequenceFlow.sourceRef,
+ target: sequenceFlow.targetRef,
+ });
+ if (sequenceFlow.name) {
+ connection.setLabel(sequenceFlow.name);
+ }
+ });
+ }
+
+ public initJsPlumbInstance(id: string) {
+ if (this.jsplumbInstanceMap.get(id)) {
+ return;
+ }
+ const jsplumbInstance = jsp.jsPlumb.getInstance();
+
+ jsplumbInstance.importDefaults({
+ Anchor: "Continuous",
+ Endpoint: "Blank",
+ Container: "pallete",
+ ReattachConnections: true,
+ Connector: ['Flowchart', {
+ stub: [0, 0],
+ cornerRadius: 5,
+ alwaysRespectStubs: true
+ }],
+ PaintStyle: {
+ stroke: "#7D8695",
+ strokeWidth: 1,
+ radius: 1,
+ outlineStroke: "transform",
+ outlineWidth: 4
+ },
+ ConnectorStyle: {
+ stroke: "#7D8695",
+ strokeWidth: 1,
+ outlineStroke: "transform",
+ outlineWidth: 4
+ },
+ ConnectorHoverStyle: {
+ stroke: "#00ABFF",
+ strokeWidth: 2,
+ outlineStroke: "transform",
+ outlineWidth: 4
+ },
+ ConnectionOverlays: [
+ ['Arrow', {
+ location: 1,
+ id: 'arrow',
+ cssClass: 'icon-port',
+ width: 11,
+ length: 12
+ }],
+ ['Label', { label: '', id: 'label' }]
+ ]
+ });
+
+ // add connection to model data while a new connection is build
+ jsplumbInstance.bind('connection', info => {
+ this.modelService.addConnection(info.connection.sourceId, info.connection.targetId);
+
+ this.subscribe4Connection(info.connection);
+
+ info.connection.bind('click', (connection, event) => {
+ if ('Label' === connection.type) {
+ return;
+ }
+ event.stopPropagation();
+ const sequenceFlow = this.modelService.getSequenceFlow(connection.sourceId, connection.targetId);
+ this.broadcastService.broadcast(this.broadcastService.showProperty, null);
+ this.broadcastService.broadcast(this.broadcastService.selectedElement, [sequenceFlow]);
+ });
+
+ info.connection.bind('dblclick', connection => {
+ if ('Label' === connection.type) {
+ return;
+ }
+ const sequenceFlow = this.modelService.getSequenceFlow(connection.sourceId, connection.targetId);
+ this.broadcastService.broadcast(this.broadcastService.showProperty, sequenceFlow);
+ });
+ });
+
+ this.jsplumbInstanceMap.set(id, jsplumbInstance);
+ }
+
+ private subscribe4Connection(connection: any) {
+ const pre = connection.sourceId + connection.targetId;
+ let sequenceFlowSubscription = this.subscriptionMap.get(pre + 'sequenceFlowSubscription');
+ if (sequenceFlowSubscription && !sequenceFlowSubscription.closed) {
+ sequenceFlowSubscription.unsubscribe();
+ }
+
+ let currentThis = this;
+ sequenceFlowSubscription = this.broadcastService.selectedElement$.subscribe(elements => {
+ let selected = false;
+ if (elements && 0 < elements.length) {
+ for (let index = 0; index < elements.length; index++) {
+ let element = elements[index];
+ if (!this.modelService.isNode(element)) {
+ let sequence = element as SequenceFlow;
+ if (sequence.sourceRef === connection.sourceId
+ && sequence.targetRef === connection.targetId) {
+ selected = true;
+ }
+ }
+ }
+ }
+ if (selected) {
+ connection.setPaintStyle({
+ stroke: '#00ABFF',
+ strokeWidth: 1,
+ radius: 1,
+ outlineStroke: "transform",
+ outlineWidth: 4
+ });
+ } else {
+ connection.setPaintStyle({
+ stroke: '#7D8695',
+ strokeWidth: 1,
+ radius: 1,
+ outlineStroke: "transform",
+ outlineWidth: 4
+ });
+ }
+ });
+ this.subscriptionMap.set(pre + 'sequenceFlowSubscription', sequenceFlowSubscription);
+ }
+
+ private unsubscription4Connection(connectionSelection: any) {
+ connectionSelection.each(connection => {
+ const pre = connection.sourceId + connection.targetId;
+ this.subscriptionMap.get(pre + 'sequenceFlowSubscription').unsubscribe();
+ });
+ }
+
+ public deleteConnect(sourceId: string, targetId: string) {
+ const sourceNode = this.modelService.getNodeMap().get(sourceId);
+ const jsplumbInstance = this.jsplumbInstanceMap.get(sourceNode.parentId);
+ const connectionSelection = jsplumbInstance.select({ source: sourceId, target: targetId });
+ this.unsubscription4Connection(connectionSelection);
+ connectionSelection.delete();
+ }
+
+ public setLabel(sourceId: string, targetId: string, label: string) {
+ const sourceNode = this.modelService.getNodeMap().get(sourceId);
+ const jsplumbInstance = this.jsplumbInstanceMap.get(sourceNode.parentId);
+ const connections = jsplumbInstance.select({ source: sourceId, target: targetId });
+ connections.setLabel(label);
+ }
+
+ public getParentNodeId(id: string): string {
+ const nodeElement = jsp.jsPlumb.getSelector('#' + id);
+ const parentNode = this.getParentNodeEl(nodeElement[0]);
+
+ return parentNode ? parentNode.id : null;
+ }
+
+ public initNode(node: WorkflowNode) {
+ const jsplumbInstance = this.jsplumbInstanceMap.get(node.parentId);
+
+ this.jsplumbInstanceMap.get(this.modelService.rootNodeId).draggable(node.id, {
+ scope: 'node',
+ filter: '.ui-resizable-handle',
+ classes: {
+ 'ui-draggable': 'dragging'
+ },
+ // grid: [5, 5],
+ drag: event => {
+ // out of container edge, reset to minimal value.
+ if (0 > event.pos[0]) {
+ event.el.style.left = '0px';
+ }
+ if (0 > event.pos[1]) {
+ event.el.style.top = '0px';
+ }
+
+ if (0 < this.selectNodes.length) {
+ let moveAll = false;
+ this.selectNodes.forEach(element => {
+ if (element.id === event.el.id) {
+ moveAll = true;
+ }
+ });
+ if (moveAll) {
+ this.selectNodes.forEach(selectNode => {
+ if (selectNode.id !== event.el.id) {
+ selectNode.position.left += event.e.movementX;
+ selectNode.position.left = 0 > selectNode.position.left ? 0 : selectNode.position.left;
+ selectNode.position.top += event.e.movementY;
+ selectNode.position.top = 0 > selectNode.position.top ? 0 : selectNode.position.top;
+ }
+ jsplumbInstance.revalidate(jsplumbInstance.getSelector('#' + selectNode.id));
+ });
+ }
+ }
+ },
+ stop: event => {
+ this.selectNodes.forEach(selectNode => {
+ jsplumbInstance.revalidate(jsplumbInstance.getSelector('#' + selectNode.id));
+ });
+ }
+ });
+
+ jsplumbInstance.makeTarget(node.id, {
+ maxConnections: -1,
+ beforeDrop: function (info) {
+ const sourceId = info.sourceId;
+ const targetId = info.targetId;
+ if (sourceId === targetId) {
+ return false;
+ }
+ const sameConnections = this.instance.getConnections({ source: sourceId, target: targetId });
+ if (sameConnections && 0 < sameConnections.length) {
+ return false;
+ }
+ return true;
+ }
+
+ });
+
+ jsplumbInstance.makeSource(node.id, {
+ filter: '.anchor, .anchor *',
+ maxConnections: -1,
+ });
+ }
+
+ public nodeDroppable(node: WorkflowNode, rank: number) {
+ const jsplumbInstance = this.jsplumbInstanceMap.get(node.parentId);
+
+ const selector = jsplumbInstance.getSelector('#' + node.id);
+ this.jsplumbInstanceMap.get(this.modelService.rootNodeId).droppable(selector, {
+ scope: 'node',
+ rank,
+ tolerance: 'pointer',
+ drop: event => {
+ if (!this.isChildNode(event.drop.el, event.drag.el)) {
+ this.drop(event);
+ }
+ return true;
+ },
+ canDrop: drag => {
+ const nodeMap = this.modelService.getNodeMap();
+ const ancestorNode = nodeMap.get(drag.el.id);
+
+ const isAncestor = this.modelService.isDescendantNode(ancestorNode, node.id);
+ return !isAncestor;
+ },
+ });
+ }
+
+ private isChildNode(childElement, parentElement) {
+ while (childElement !== parentElement) {
+ childElement = childElement.parentNode;
+ if (childElement.classList.contains('canvas')) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private drop(event) {
+ const dragEl = event.drag.el;
+ const dropEl = event.drop.el;
+
+ this.resizeParent(dragEl, dropEl);
+
+ const nodeLeft = dragEl.getBoundingClientRect().left;
+ const nodeTop = dragEl.getBoundingClientRect().top;
+ const parentLeft = dropEl.getBoundingClientRect().left;
+ const parentTop = dropEl.getBoundingClientRect().top;
+ const left = nodeLeft - parentLeft + dropEl.scrollLeft;
+ const top = nodeTop - parentTop + dropEl.scrollTop;
+ dragEl.style.top = top + 'px';
+ dragEl.style.left = left + 'px';
+
+ // 12 is title height
+ this.modelService.updatePosition(dragEl.id, left, top, dragEl.getBoundingClientRect().width, dragEl.getBoundingClientRect().height - 12);
+
+ const originalParentNode = this.getParentNodeEl(dragEl);
+ const originalParentNodeId = originalParentNode ? originalParentNode.id : this.modelService.rootNodeId;
+
+ const targetParentNodeId = dropEl.classList.contains('node') ? dropEl.id : this.modelService.rootNodeId;
+ this.changeParent(dragEl.id, originalParentNodeId, targetParentNodeId);
+ }
+
+ private changeParent(id: string, originalParentNodeId: string, targetParentNodeId: string) {
+ if (originalParentNodeId !== targetParentNodeId) {
+ this.jsplumbInstanceMap.get(originalParentNodeId).removeAllEndpoints(id);
+ this.modelService.changeParent(id, originalParentNodeId, targetParentNodeId);
+ }
+ }
+
+ private getParentNodeEl(element) {
+ while (!(element.parentNode.classList.contains('node') || element.parentNode.classList.contains('canvas'))) {
+ element = element.parentNode;
+ }
+
+ if (element.parentNode.classList.contains('canvas')) { // top level node
+ return null;
+ } else {
+ return element.parentNode;
+ }
+ }
+
+ public canvasDroppable() {
+ const jsplumbInstance = this.jsplumbInstanceMap.get(this.modelService.rootNodeId);
+ const canvasSelector = jsplumbInstance.getSelector('.canvas');
+ jsplumbInstance.droppable(canvasSelector, {
+ scope: 'node',
+ rank: 0,
+ grid: [5, 5],
+ drop: event => this.drop(event),
+ });
+ }
+
+ public buttonDraggable() {
+ const jsplumbInstance = this.jsplumbInstanceMap.get(this.modelService.rootNodeId);
+ const selector = jsplumbInstance.getSelector('.item');
+ jsplumbInstance.draggable(selector, {
+ scope: 'btn',
+ clone: true
+ });
+ }
+
+ public buttonDroppable() {
+ const jsplumbInstance = this.jsplumbInstanceMap.get(this.modelService.rootNodeId);
+ const selector = jsplumbInstance.getSelector('.canvas');
+ jsplumbInstance.droppable(selector, {
+ scope: 'btn',
+ // grid: [5, 5],
+ drop: event => {
+ const el = jsplumbInstance.getSelector(event.drag.el);
+ const type = el.attributes.nodeType.value;
+ // Mouse position minus drop canvas start position plus scroll position.
+ let left = event.e.x - event.drop.pagePosition[0] + event.drop.el.scrollLeft;
+ let top = event.e.y - event.drop.pagePosition[1] + event.drop.el.scrollTop;
+ if (0 > left) {
+ left = 0;
+ }
+ if (0 > top) {
+ top = 0;
+ }
+ const name = event.drag.el.children[1].innerText;
+ this.modelService.addNode(name, type, left, top);
+ },
+ });
+ }
+
+ public remove(node: WorkflowNode) {
+ const jsplumbInstance = this.jsplumbInstanceMap.get(node.parentId);
+
+ // unsubscription4Connection
+ const connectionsAsSource = jsplumbInstance.select({ source: node.id });
+ this.unsubscription4Connection(connectionsAsSource);
+ const connectionsAsTarget = jsplumbInstance.select({ target: node.id });
+ this.unsubscription4Connection(connectionsAsTarget);
+
+ jsplumbInstance.remove(node.id);
+ }
+
+ public resizeParent(element: any, parentElement: any) {
+ if (parentElement.classList.contains(this.rootClass)) {
+ return;
+ }
+
+ if (!parentElement.classList.contains('node')) {
+ this.resizeParent(element, parentElement.parentNode);
+ return;
+ }
+
+ const leftResized = this.resizeParentLeft(element, parentElement);
+ const rightResized = this.resizeParentRight(element, parentElement);
+ const topResized = this.resizeParentTop(element, parentElement);
+ const bottomResized = this.resizeParentBottom(element, parentElement);
+
+ if (leftResized || rightResized || topResized || bottomResized) {
+ if (parentElement.classList.contains('node')) {
+ const rect = parentElement.getBoundingClientRect();
+ this.modelService.updatePosition(parentElement.id,
+ parentElement.offsetLeft,
+ parentElement.offsetTop,
+ // title height
+ rect.width, rect.height - 12);
+ }
+ this.resizeParent(parentElement, parentElement.parentNode);
+ }
+ }
+
+ private resizeParentLeft(element: any, parentElement: any): boolean {
+ let resized = false;
+
+ const actualLeft = element.getBoundingClientRect().left;
+ const actualParentLeft = parentElement.getBoundingClientRect().left;
+
+ if (actualLeft - this.padding < actualParentLeft) {
+ const width = actualParentLeft - actualLeft + this.padding;
+
+ this.translateElement(parentElement, -width, 0, width, 0);
+ this.translateChildren(parentElement, element, width, 0);
+ resized = true;
+ }
+
+ return resized;
+ }
+
+ private resizeParentRight(element: any, parentElement: any): boolean {
+ let resized = false;
+
+ const actualLeft = element.getBoundingClientRect().left;
+ const actualRight = actualLeft + element.offsetWidth;
+
+ const actualParentLeft = parentElement.getBoundingClientRect().left;
+
+ if ((actualParentLeft + parentElement.offsetWidth) < actualRight + this.padding) {
+ this.setElementWidth(parentElement, actualRight + this.padding - actualParentLeft);
+ resized = true;
+ }
+
+ return resized;
+ }
+
+ private resizeParentBottom(element: any, parentElement: any): boolean {
+ let resized = false;
+
+ const actualTop = element.getBoundingClientRect().top;
+ const actualBottom = actualTop + element.offsetHeight;
+
+ const actualParentTop = parentElement.getBoundingClientRect().top;
+ const actualParentBottom = actualParentTop + parentElement.offsetHeight;
+
+ if (actualParentBottom < actualBottom + this.padding) {
+ this.setElementHeight(parentElement, actualBottom + this.padding - actualParentTop);
+ resized = true;
+ }
+
+ return resized;
+ }
+
+ private resizeParentTop(element: any, parentElement: any): boolean {
+ let resized = false;
+
+ const actualTop = element.getBoundingClientRect().top;
+ const actualParentTop = parentElement.getBoundingClientRect().top;
+
+ if (actualTop - this.padding < actualParentTop) {
+ const height = actualParentTop - actualTop + this.padding;
+
+ this.translateElement(parentElement, 0, -height, 0, height);
+ this.translateChildren(parentElement, element, 0, height);
+ resized = true;
+ }
+
+ return resized;
+ }
+
+ private translateElement(element, left: number, top: number, width: number, height: number) {
+ const offsetLeft = element.offsetLeft + left;
+ element.style.left = offsetLeft + 'px';
+
+ const offsetTop = element.offsetTop + top;
+ element.style.top = offsetTop + 'px';
+
+ const offsetWidth = element.offsetWidth + width;
+ element.style.width = offsetWidth + 'px';
+
+ const offsetHeight = element.offsetHeight + height;
+ element.style.height = offsetHeight + 'px';
+
+ if (element.classList.contains('node')) {
+ const node = this.modelService.getNodeMap().get(element.id);
+ this.jsplumbInstanceMap.get(node.parentId).revalidate(element.id);
+ }
+ }
+
+ private translateChildren(parentElment, excludeElement, left: number, top: number) {
+ const len = parentElment.children.length;
+ for (let i = 0; i < len; i++) {
+ const childElment = parentElment.children[i];
+ if (childElment.localName === 'b4t-node') {
+ this.translateElement(childElment.children[0], left, top, 0, 0);
+ }
+ }
+ }
+
+ private setElementHeight(element, height: number) {
+ element.style.height = height + 'px';
+ }
+
+ private setElementWidth(element, width: number) {
+ element.style.width = width + 'px';
+ }
+
+ private getActualPosition(element, offset: string) {
+ let actualPosition = element[offset];
+ let current = element.offsetParent;
+ while (current !== null) {
+ actualPosition += element[offset];
+ current = current.offsetParent;
+ }
+ return actualPosition;
+ }
+}
diff --git a/sdc-workflow-designer-ui/src/app/services/model.service.ts b/sdc-workflow-designer-ui/src/app/services/model.service.ts
index 81cad031..b0ce69f3 100644
--- a/sdc-workflow-designer-ui/src/app/services/model.service.ts
+++ b/sdc-workflow-designer-ui/src/app/services/model.service.ts
@@ -1,513 +1,513 @@
-/**
- * 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 { isNullOrUndefined } from 'util';
-
-import { PlanModel } from '../model/plan-model';
-import { PlanTreeviewItem } from '../model/plan-treeview-item';
-import { RestConfig } from '../model/rest-config';
-import { Swagger, SwaggerModel, SwaggerModelSimple, SwaggerPrimitiveObject, SwaggerReferenceObject } from '../model/swagger';
-import { ErrorEvent } from '../model/workflow/error-event';
-import { IntermediateCatchEvent } from '../model/workflow/intermediate-catch-event';
-import { NodeType } from '../model/workflow/node-type.enum';
-import { Parameter } from '../model/workflow/parameter';
-import { Position } from '../model/workflow/position';
-import { RestTask } from '../model/workflow/rest-task';
-import { SequenceFlow } from '../model/workflow/sequence-flow';
-import { StartEvent } from '../model/workflow/start-event';
-import { SubProcess } from '../model/workflow/sub-process';
-import { ToscaNodeTask } from '../model/workflow/tosca-node-task';
-import { WorkflowNode } from '../model/workflow/workflow-node';
-import { NodeTemplate } from '../model/topology/node-template';
-import { ValueSource } from '../model/value-source.enum';
-import { BroadcastService } from './broadcast.service';
-import { RestService } from './rest.service';
-import { SwaggerTreeConverterService } from './swagger-tree-converter.service';
-import { ScriptTask } from "../model/workflow/script-task";
-import { TimerEventDefinition, TimerEventDefinitionType } from "../model/workflow/timer-event-definition";
-
-/**
- * ModelService
- * provides all operations about plan model.
- */
-@Injectable()
-export class ModelService {
- public rootNodeId = 'root';
-
- private planModel: PlanModel = new PlanModel();
-
- constructor(private broadcastService: BroadcastService, private restService: RestService) {
- this.broadcastService.planModel$.subscribe(plan => {
- plan.nodes.forEach(node => {
- switch (node.type) {
- case NodeType[NodeType.startEvent]:
- node.position.width = 56;
- node.position.height = 56;
- break;
- case NodeType[NodeType.endEvent]:
- node.position.width = 56;
- node.position.height = 56;
- break;
- case NodeType[NodeType.restTask]:
- node.position.width = 56;
- node.position.height = 56;
- break;
- case NodeType[NodeType.errorStartEvent]:
- case NodeType[NodeType.errorEndEvent]:
- node.position.width = 26;
- node.position.height = 26;
- break;
- case NodeType[NodeType.toscaNodeManagementTask]:
- node.position.width = 56;
- node.position.height = 56;
- break;
- case NodeType[NodeType.subProcess]:
- node.position.width = 56;
- node.position.height = 56;
- break;
- case NodeType[NodeType.intermediateCatchEvent]:
- node.position.width = 56;
- node.position.height = 56;
- break;
- case NodeType[NodeType.scriptTask]:
- node.position.width = 56;
- node.position.height = 56;
- break;
- case NodeType[NodeType.exclusiveGateway]:
- case NodeType[NodeType.parallelGateway]:
- node.position.width = 26;
- node.position.height = 26;
- break;
- default:
- node.position.width = 56;
- node.position.height = 56;
- break;
- }
- });
- this.planModel = plan;
- });
- this.broadcastService.updateModelRestConfig$.subscribe(restConfigs => {
- this.updateRestConfig(restConfigs);
- });
- }
-
- public getChildrenNodes(parentId: string): WorkflowNode[] {
- if (!parentId || parentId === this.rootNodeId) {
- return this.planModel.nodes;
- } else {
- const node = this.getNodeMap().get(parentId);
- if (node.type === 'subProcess') {
- return (<SubProcess>node).children;
- } else {
- return [];
- }
- }
- }
-
- public getNodes(): WorkflowNode[] {
- return this.planModel.nodes;
- }
-
- public getSequenceFlow(sourceRef: string, targetRef: string): SequenceFlow {
- const node = this.getNodeMap().get(sourceRef);
- if (node) {
- const sequenceFlow = node.connection.find(tmp => tmp.targetRef === targetRef);
- return sequenceFlow;
- } else {
- return null;
- }
- }
-
- public addNode(name: string, type: string, left: number, top: number) {
- const id = this.createId();
- const workflowPos = new Position(left, top);
- const node = this.createNodeByType(id, name, type, workflowPos);
- this.planModel.nodes.push(node);
- }
-
- private createNodeByType(id: string, name: string, type: string, position: Position): WorkflowNode {
- const bigPosition = new Position(position.left, position.top, 56, 56);
- const smallPosition = new Position(position.left, position.top, 26, 26);
- switch (type) {
- case NodeType[NodeType.startEvent]:
- let startEventNode: StartEvent = {
- id: id, type: type, name: name, parentId: this.rootNodeId,
- position: bigPosition, connection: [], parameters: []
- };
- return startEventNode;
- case NodeType[NodeType.endEvent]:
- let endEventNode: WorkflowNode = {
- id: id, type: type, name: name, parentId: this.rootNodeId,
- position: bigPosition, connection: []
- };
- return endEventNode;
- case NodeType[NodeType.restTask]:
- let restTaskNode: RestTask = {
- id: id, type: type, name: name, parentId: this.rootNodeId,
- position: bigPosition, connection: [], produces: [], consumes: [], parameters: [], responses: []
- };
- return restTaskNode;
- case NodeType[NodeType.errorStartEvent]:
- case NodeType[NodeType.errorEndEvent]:
- let errorEventNode: ErrorEvent = {
- id: id, type: type, name: '', parentId: this.rootNodeId,
- position: smallPosition, connection: [], parameter: new Parameter('errorRef', '', ValueSource[ValueSource.String])
- };
- return errorEventNode;
- case NodeType[NodeType.toscaNodeManagementTask]:
- let toscaNodeTask: ToscaNodeTask = {
- id: id, type: type, name: name, parentId: this.rootNodeId,
- position: bigPosition, connection: [], input: [], output: [], template: new NodeTemplate()
- };
- return toscaNodeTask;
- case NodeType[NodeType.subProcess]:
- let subProcess: SubProcess = {
- id: id, type: type, name: name, parentId: this.rootNodeId,
- position: bigPosition, connection: [], children: []
- };
- return subProcess;
- case NodeType[NodeType.intermediateCatchEvent]:
- let intermediateCatchEvent: IntermediateCatchEvent = {
- id: id, type: type, name: name, parentId: this.rootNodeId,
- position: bigPosition, connection: [], timerEventDefinition: <TimerEventDefinition>{ type: TimerEventDefinitionType[TimerEventDefinitionType.timeDuration] }
- };
- return intermediateCatchEvent;
- case NodeType[NodeType.scriptTask]:
- let scriptTask: ScriptTask = {
- id: id, type: type, name: name, parentId: this.rootNodeId,
- position: bigPosition, connection: [], scriptFormat: 'JavaScript'
- };
- return scriptTask;
- case NodeType[NodeType.exclusiveGateway]:
- case NodeType[NodeType.parallelGateway]:
- let getway: WorkflowNode = {
- id: id, type: type, name: '', parentId: this.rootNodeId,
- position: smallPosition, connection: []
- };
- return getway;
- default:
- let node: WorkflowNode = {
- id: id, type: type, name: name, parentId: this.rootNodeId,
- position: bigPosition, connection: []
- };
- return node;
- }
- }
-
- public isNode(object: any): boolean {
- return undefined !== object.type;
- }
-
- // public createNodeByJson(obj: any): WorkflowNode {
- // let node;
- // switch (obj.type) {
- // case NodeType[NodeType.startEvent]:
- // node = new StartEvent(obj.name, obj.id, obj.type, this.rootNodeId, obj.position);
- // node.parameters = obj.parameters;
- // return node;
- // case NodeType[NodeType.restTask]:
- // node = new RestTask(obj.name, obj.id, obj.type, this.rootNodeId, obj.position);
- // node.
- // case NodeType[NodeType.errorStartEvent]:
- // return new ErrorEvent(type, id, type, this.rootNodeId, position);
- // case NodeType[NodeType.errorEndEvent]:
- // return new ErrorEvent(type, id, type, this.rootNodeId, position);
- // case NodeType[NodeType.toscaNodeManagementTask]:
- // return new ToscaNodeTask(type, id, type, this.rootNodeId, position);
- // case NodeType[NodeType.subProcess]:
- // return new SubProcess(type, id, type, this.rootNodeId, position);
- // case NodeType[NodeType.intermediateCatchEvent]:
- // return new IntermediateCatchEvent(type, id, type, this.rootNodeId, position);
- // case NodeType[NodeType.scriptTask]:
- // return new ScriptTask(type, id, type, this.rootNodeId, position);
- // default:
- // return new WorkflowNode(type, id, type, this.rootNodeId, position);
- // }
- // return node;
- // }
-
- public changeParent(id: string, originalParentId: string, targetParentId: string) {
- if (originalParentId === targetParentId) {
- return;
- }
-
- const node: WorkflowNode = this.deleteNode(originalParentId, id);
- node.parentId = targetParentId;
-
- if (targetParentId) {
- this.addChild(targetParentId, node);
- } else {
- this.planModel.nodes.push(node);
- }
- }
-
- public updatePosition(id: string, left: number, top: number, width: number, height: number) {
- const node = this.getNodeMap().get(id);
- node.position.left = left;
- node.position.top = top;
- node.position.width = width;
- node.position.height = height;
- }
-
- public updateRestConfig(restConfigs: RestConfig[]): void {
- this.planModel.configs = { restConfigs: restConfigs };
- // console.log(this.planModel.configs);
- }
-
- public getNodeMap(): Map<string, WorkflowNode> {
- const map = new Map<string, WorkflowNode>();
- this.toNodeMap(this.planModel.nodes, map);
- return map;
- }
-
- public getAncestors(id: string): WorkflowNode[] {
- const nodeMap = this.getNodeMap();
- const ancestors = [];
-
- let ancestor = nodeMap.get(id);
- do {
- ancestor = this.getParentNode(ancestor.id, nodeMap);
- if (ancestor && ancestor.id !== id) {
- ancestors.push(ancestor);
- }
- } while (ancestor);
-
- return ancestors;
- }
-
- private getParentNode(id: string, nodeMap: Map<string, WorkflowNode>): WorkflowNode {
- let parentNode;
- nodeMap.forEach((node, key) => {
- if (NodeType[NodeType.subProcess] === node.type) {
- const childNode = (<SubProcess>node).children.find(child => child.id === id);
- if (childNode) {
- parentNode = node;
- }
- }
-
- });
-
- return parentNode;
- }
-
- public isDescendantNode(node: WorkflowNode, descendantId: string): boolean {
- if (NodeType[NodeType.subProcess] !== node.type) {
- return false;
- }
- const tmp = (<SubProcess>node).children.find(child => {
- return child.id === descendantId || (NodeType[NodeType.subProcess] === child.type && this.isDescendantNode(<SubProcess>child, descendantId));
- });
-
- return tmp !== undefined;
- }
-
- private toNodeMap(nodes: WorkflowNode[], map: Map<string, WorkflowNode>) {
- nodes.forEach(node => {
- if (node.type === 'subProcess') {
- this.toNodeMap((<SubProcess>node).children, map);
- }
- map.set(node.id, node);
- });
- }
-
- public addConnection(sourceId: string, targetId: string) {
- const node = this.getNodeMap().get(sourceId);
- if (node) {
- const index = node.connection.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId);
- if (index === -1) {
- const sequenceFlow: SequenceFlow = { sourceRef: sourceId, targetRef: targetId };
- node.connection.push(sequenceFlow);
- }
- }
- }
-
- public deleteConnection(sourceId: string, targetId: string) {
- const node = this.getNodeMap().get(sourceId);
- if (node) {
- const index = node.connection.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId);
- if (index !== -1) {
- node.connection.splice(index, 1);
- }
- }
- }
-
- public deleteNode(parentId: string, nodeId: string): WorkflowNode {
- const nodeMap = this.getNodeMap();
-
- const nodes = this.getChildrenNodes(parentId);
-
- // delete related connections
- nodes.forEach(node => this.deleteConnection(node.id, nodeId));
-
- // delete current node
- const index = nodes.findIndex(node => node.id === nodeId);
- if (index !== -1) {
- const node = nodes.splice(index, 1)[0];
- node.connection = [];
- return node;
- }
-
- return null;
- }
-
- public addChild(parentId: string, child: WorkflowNode) {
- this.getChildrenNodes(parentId).push(child);
- }
-
- public deleteChild(node: SubProcess, id: string): WorkflowNode {
- const index = node.children.findIndex(child => child.id === id);
- if (index !== -1) {
- const deletedNode = node.children.splice(index, 1);
- return deletedNode[0];
- }
-
- return null;
- }
-
- public getPlanParameters(nodeId: string): PlanTreeviewItem[] {
- const preNodeList = new Array<WorkflowNode>();
- this.getPreNodes(nodeId, this.getNodeMap(), preNodeList);
-
- return this.loadNodeOutputs(preNodeList);
- }
-
- private loadNodeOutputs(nodes: WorkflowNode[]): PlanTreeviewItem[] {
- const params = new Array<PlanTreeviewItem>();
- nodes.forEach(node => {
- switch (node.type) {
- case NodeType[NodeType.startEvent]:
- params.push(this.loadOutput4StartEvent(<StartEvent>node));
- break;
- case NodeType[NodeType.toscaNodeManagementTask]:
- params.push(this.loadOutput4ToscaNodeTask(<ToscaNodeTask>node));
- break;
- case NodeType[NodeType.restTask]:
- params.push(this.loadOutput4RestTask(<RestTask>node));
- break;
- default:
- break;
- }
- });
-
- return params;
- }
-
- private loadOutput4StartEvent(node: StartEvent): PlanTreeviewItem {
- const startItem = new PlanTreeviewItem(node.name, `[${node.id}]`, [], false);
- node.parameters.map(param =>
- startItem.children.push(new PlanTreeviewItem(param.name, `[${param.name}]`, [])));
- return startItem;
- }
-
- private loadOutput4ToscaNodeTask(node: ToscaNodeTask): PlanTreeviewItem {
- const item = new PlanTreeviewItem(node.name, `[${node.id}]`, [], false);
- item.children.push(this.createStatusCodeTreeViewItem(node.id));
- const responseItem = this.createResponseTreeViewItem(node.id);
- item.children.push(responseItem);
-
- node.output.map(param =>
- responseItem.children.push(new PlanTreeviewItem(param.name, `${responseItem.value}.[${param.name}]`, [])));
- return item;
- }
-
- private loadOutput4RestTask(node: RestTask): PlanTreeviewItem {
- const item = new PlanTreeviewItem(node.name, `[${node.id}]`, [], false);
- item.children.push(this.createStatusCodeTreeViewItem(node.id));
-
- if (node.responses.length !== 0) { // load rest responses
- const responseItem = this.createResponseTreeViewItem(node.id);
- item.children.push(responseItem);
- // todo: should list all available response or only the first one?
- if (node.responses[0]) {
- const swagger = this.restService.getSwaggerInfo(node.restConfigId);
- const SwaggerReferenceObject = node.responses[0].schema as SwaggerReferenceObject;
- const swaggerDefinition = this.restService.getDefinition(swagger, SwaggerReferenceObject.$ref);
- this.loadParamsBySwaggerDefinition(responseItem, swagger, swaggerDefinition);
- }
- }
-
- return item;
- }
-
- private loadParamsBySwaggerDefinition(parentItem: PlanTreeviewItem, swagger: Swagger, definition: any) {
- Object.getOwnPropertyNames(definition.properties).map(key => {
- const property = definition.properties[key];
- const value = `${parentItem.value}.[${key}]`;
- const propertyItem = new PlanTreeviewItem(key, value, []);
- parentItem.children.push(propertyItem);
-
- // reference to swagger.ts function getSchemaObject()
- if (property instanceof SwaggerReferenceObject) {
- // handle reference parameter.
- const propertyDefinition = this.restService.getDefinition(swagger, property.$ref);
- this.loadParamsBySwaggerDefinition(propertyItem, swagger, propertyDefinition);
- } else if (property instanceof SwaggerModelSimple) {
- // handle object parameter.
- this.loadParamsBySwaggerDefinition(propertyItem, swagger, property);
- } else {
- // skip
- }
-
- return propertyItem;
- });
- }
-
- private createStatusCodeTreeViewItem(nodeId: string): PlanTreeviewItem {
- return new PlanTreeviewItem('statusCode', `[${nodeId}].[statusCode]`, []);
- }
-
- private createResponseTreeViewItem(nodeId: string): PlanTreeviewItem {
- return new PlanTreeviewItem('response', `[${nodeId}].[responseBody]`, []);
- }
-
- public getPreNodes(nodeId: string, nodeMap: Map<string, WorkflowNode>, preNodes: WorkflowNode[]) {
- const preNode4CurrentNode = [];
- nodeMap.forEach(node => {
- if (this.isPreNode(node, nodeId)) {
- const existNode = preNodes.find(tmpNode => tmpNode.id === node.id);
- if (existNode) {
- // current node already exists. this could avoid loop circle.
- } else {
- preNode4CurrentNode.push(node);
- preNodes.push(node);
- }
- }
- });
-
- preNode4CurrentNode.forEach(node => this.getPreNodes(node.id, nodeMap, preNodes));
- }
-
- public isPreNode(preNode: WorkflowNode, id: string): boolean {
- const targetNode = preNode.connection.find(connection => connection.targetRef === id);
- return targetNode !== undefined;
- }
-
- public save() {
- console.log('****************** save data *********************');
- console.log(this.planModel);
-
- this.broadcastService.broadcast(this.broadcastService.saveEvent, this.planModel);
- }
-
- private createId() {
- const nodeMap = this.getNodeMap();
-
- for (let i = 0; i < nodeMap.size; i++) {
- const key = 'node' + i;
- if (!nodeMap.get(key)) {
- return key;
- }
- }
-
- return 'node' + nodeMap.size;
- }
-}
+/**
+ * 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 { isNullOrUndefined } from 'util';
+
+import { PlanModel } from '../model/plan-model';
+import { PlanTreeviewItem } from '../model/plan-treeview-item';
+import { RestConfig } from '../model/rest-config';
+import { Swagger, SwaggerModel, SwaggerModelSimple, SwaggerPrimitiveObject, SwaggerReferenceObject } from '../model/swagger';
+import { ErrorEvent } from '../model/workflow/error-event';
+import { IntermediateCatchEvent } from '../model/workflow/intermediate-catch-event';
+import { NodeType } from '../model/workflow/node-type.enum';
+import { Parameter } from '../model/workflow/parameter';
+import { Position } from '../model/workflow/position';
+import { RestTask } from '../model/workflow/rest-task';
+import { SequenceFlow } from '../model/workflow/sequence-flow';
+import { StartEvent } from '../model/workflow/start-event';
+import { SubProcess } from '../model/workflow/sub-process';
+import { ToscaNodeTask } from '../model/workflow/tosca-node-task';
+import { WorkflowNode } from '../model/workflow/workflow-node';
+import { NodeTemplate } from '../model/topology/node-template';
+import { ValueSource } from '../model/value-source.enum';
+import { BroadcastService } from './broadcast.service';
+import { RestService } from './rest.service';
+import { SwaggerTreeConverterService } from './swagger-tree-converter.service';
+import { ScriptTask } from "../model/workflow/script-task";
+import { TimerEventDefinition, TimerEventDefinitionType } from "../model/workflow/timer-event-definition";
+
+/**
+ * ModelService
+ * provides all operations about plan model.
+ */
+@Injectable()
+export class ModelService {
+ public rootNodeId = 'root';
+
+ private planModel: PlanModel = new PlanModel();
+
+ constructor(private broadcastService: BroadcastService, private restService: RestService) {
+ this.broadcastService.planModel$.subscribe(plan => {
+ plan.nodes.forEach(node => {
+ switch (node.type) {
+ case NodeType[NodeType.startEvent]:
+ node.position.width = 56;
+ node.position.height = 56;
+ break;
+ case NodeType[NodeType.endEvent]:
+ node.position.width = 56;
+ node.position.height = 56;
+ break;
+ case NodeType[NodeType.restTask]:
+ node.position.width = 56;
+ node.position.height = 56;
+ break;
+ case NodeType[NodeType.errorStartEvent]:
+ case NodeType[NodeType.errorEndEvent]:
+ node.position.width = 26;
+ node.position.height = 26;
+ break;
+ case NodeType[NodeType.toscaNodeManagementTask]:
+ node.position.width = 56;
+ node.position.height = 56;
+ break;
+ case NodeType[NodeType.subProcess]:
+ node.position.width = 56;
+ node.position.height = 56;
+ break;
+ case NodeType[NodeType.intermediateCatchEvent]:
+ node.position.width = 56;
+ node.position.height = 56;
+ break;
+ case NodeType[NodeType.scriptTask]:
+ node.position.width = 56;
+ node.position.height = 56;
+ break;
+ case NodeType[NodeType.exclusiveGateway]:
+ case NodeType[NodeType.parallelGateway]:
+ node.position.width = 26;
+ node.position.height = 26;
+ break;
+ default:
+ node.position.width = 56;
+ node.position.height = 56;
+ break;
+ }
+ });
+ this.planModel = plan;
+ });
+ this.broadcastService.updateModelRestConfig$.subscribe(restConfigs => {
+ this.updateRestConfig(restConfigs);
+ });
+ }
+
+ public getChildrenNodes(parentId: string): WorkflowNode[] {
+ if (!parentId || parentId === this.rootNodeId) {
+ return this.planModel.nodes;
+ } else {
+ const node = this.getNodeMap().get(parentId);
+ if (node.type === 'subProcess') {
+ return (<SubProcess>node).children;
+ } else {
+ return [];
+ }
+ }
+ }
+
+ public getNodes(): WorkflowNode[] {
+ return this.planModel.nodes;
+ }
+
+ public getSequenceFlow(sourceRef: string, targetRef: string): SequenceFlow {
+ const node = this.getNodeMap().get(sourceRef);
+ if (node) {
+ const sequenceFlow = node.connection.find(tmp => tmp.targetRef === targetRef);
+ return sequenceFlow;
+ } else {
+ return null;
+ }
+ }
+
+ public addNode(name: string, type: string, left: number, top: number) {
+ const id = this.createId();
+ const workflowPos = new Position(left, top);
+ const node = this.createNodeByType(id, name, type, workflowPos);
+ this.planModel.nodes.push(node);
+ }
+
+ private createNodeByType(id: string, name: string, type: string, position: Position): WorkflowNode {
+ const bigPosition = new Position(position.left, position.top, 56, 56);
+ const smallPosition = new Position(position.left, position.top, 26, 26);
+ switch (type) {
+ case NodeType[NodeType.startEvent]:
+ let startEventNode: StartEvent = {
+ id: id, type: type, name: name, parentId: this.rootNodeId,
+ position: bigPosition, connection: [], parameters: []
+ };
+ return startEventNode;
+ case NodeType[NodeType.endEvent]:
+ let endEventNode: WorkflowNode = {
+ id: id, type: type, name: name, parentId: this.rootNodeId,
+ position: bigPosition, connection: []
+ };
+ return endEventNode;
+ case NodeType[NodeType.restTask]:
+ let restTaskNode: RestTask = {
+ id: id, type: type, name: name, parentId: this.rootNodeId,
+ position: bigPosition, connection: [], produces: [], consumes: [], parameters: [], responses: []
+ };
+ return restTaskNode;
+ case NodeType[NodeType.errorStartEvent]:
+ case NodeType[NodeType.errorEndEvent]:
+ let errorEventNode: ErrorEvent = {
+ id: id, type: type, name: '', parentId: this.rootNodeId,
+ position: smallPosition, connection: [], parameter: new Parameter('errorRef', '', ValueSource[ValueSource.String])
+ };
+ return errorEventNode;
+ case NodeType[NodeType.toscaNodeManagementTask]:
+ let toscaNodeTask: ToscaNodeTask = {
+ id: id, type: type, name: name, parentId: this.rootNodeId,
+ position: bigPosition, connection: [], input: [], output: [], template: new NodeTemplate()
+ };
+ return toscaNodeTask;
+ case NodeType[NodeType.subProcess]:
+ let subProcess: SubProcess = {
+ id: id, type: type, name: name, parentId: this.rootNodeId,
+ position: bigPosition, connection: [], children: []
+ };
+ return subProcess;
+ case NodeType[NodeType.intermediateCatchEvent]:
+ let intermediateCatchEvent: IntermediateCatchEvent = {
+ id: id, type: type, name: name, parentId: this.rootNodeId,
+ position: bigPosition, connection: [], timerEventDefinition: <TimerEventDefinition>{ type: TimerEventDefinitionType[TimerEventDefinitionType.timeDuration] }
+ };
+ return intermediateCatchEvent;
+ case NodeType[NodeType.scriptTask]:
+ let scriptTask: ScriptTask = {
+ id: id, type: type, name: name, parentId: this.rootNodeId,
+ position: bigPosition, connection: [], scriptFormat: 'JavaScript'
+ };
+ return scriptTask;
+ case NodeType[NodeType.exclusiveGateway]:
+ case NodeType[NodeType.parallelGateway]:
+ let getway: WorkflowNode = {
+ id: id, type: type, name: '', parentId: this.rootNodeId,
+ position: smallPosition, connection: []
+ };
+ return getway;
+ default:
+ let node: WorkflowNode = {
+ id: id, type: type, name: name, parentId: this.rootNodeId,
+ position: bigPosition, connection: []
+ };
+ return node;
+ }
+ }
+
+ public isNode(object: any): boolean {
+ return undefined !== object.type;
+ }
+
+ // public createNodeByJson(obj: any): WorkflowNode {
+ // let node;
+ // switch (obj.type) {
+ // case NodeType[NodeType.startEvent]:
+ // node = new StartEvent(obj.name, obj.id, obj.type, this.rootNodeId, obj.position);
+ // node.parameters = obj.parameters;
+ // return node;
+ // case NodeType[NodeType.restTask]:
+ // node = new RestTask(obj.name, obj.id, obj.type, this.rootNodeId, obj.position);
+ // node.
+ // case NodeType[NodeType.errorStartEvent]:
+ // return new ErrorEvent(type, id, type, this.rootNodeId, position);
+ // case NodeType[NodeType.errorEndEvent]:
+ // return new ErrorEvent(type, id, type, this.rootNodeId, position);
+ // case NodeType[NodeType.toscaNodeManagementTask]:
+ // return new ToscaNodeTask(type, id, type, this.rootNodeId, position);
+ // case NodeType[NodeType.subProcess]:
+ // return new SubProcess(type, id, type, this.rootNodeId, position);
+ // case NodeType[NodeType.intermediateCatchEvent]:
+ // return new IntermediateCatchEvent(type, id, type, this.rootNodeId, position);
+ // case NodeType[NodeType.scriptTask]:
+ // return new ScriptTask(type, id, type, this.rootNodeId, position);
+ // default:
+ // return new WorkflowNode(type, id, type, this.rootNodeId, position);
+ // }
+ // return node;
+ // }
+
+ public changeParent(id: string, originalParentId: string, targetParentId: string) {
+ if (originalParentId === targetParentId) {
+ return;
+ }
+
+ const node: WorkflowNode = this.deleteNode(originalParentId, id);
+ node.parentId = targetParentId;
+
+ if (targetParentId) {
+ this.addChild(targetParentId, node);
+ } else {
+ this.planModel.nodes.push(node);
+ }
+ }
+
+ public updatePosition(id: string, left: number, top: number, width: number, height: number) {
+ const node = this.getNodeMap().get(id);
+ node.position.left = left;
+ node.position.top = top;
+ node.position.width = width;
+ node.position.height = height;
+ }
+
+ public updateRestConfig(restConfigs: RestConfig[]): void {
+ this.planModel.configs = { restConfigs: restConfigs };
+ // console.log(this.planModel.configs);
+ }
+
+ public getNodeMap(): Map<string, WorkflowNode> {
+ const map = new Map<string, WorkflowNode>();
+ this.toNodeMap(this.planModel.nodes, map);
+ return map;
+ }
+
+ public getAncestors(id: string): WorkflowNode[] {
+ const nodeMap = this.getNodeMap();
+ const ancestors = [];
+
+ let ancestor = nodeMap.get(id);
+ do {
+ ancestor = this.getParentNode(ancestor.id, nodeMap);
+ if (ancestor && ancestor.id !== id) {
+ ancestors.push(ancestor);
+ }
+ } while (ancestor);
+
+ return ancestors;
+ }
+
+ private getParentNode(id: string, nodeMap: Map<string, WorkflowNode>): WorkflowNode {
+ let parentNode;
+ nodeMap.forEach((node, key) => {
+ if (NodeType[NodeType.subProcess] === node.type) {
+ const childNode = (<SubProcess>node).children.find(child => child.id === id);
+ if (childNode) {
+ parentNode = node;
+ }
+ }
+
+ });
+
+ return parentNode;
+ }
+
+ public isDescendantNode(node: WorkflowNode, descendantId: string): boolean {
+ if (NodeType[NodeType.subProcess] !== node.type) {
+ return false;
+ }
+ const tmp = (<SubProcess>node).children.find(child => {
+ return child.id === descendantId || (NodeType[NodeType.subProcess] === child.type && this.isDescendantNode(<SubProcess>child, descendantId));
+ });
+
+ return tmp !== undefined;
+ }
+
+ private toNodeMap(nodes: WorkflowNode[], map: Map<string, WorkflowNode>) {
+ nodes.forEach(node => {
+ if (node.type === 'subProcess') {
+ this.toNodeMap((<SubProcess>node).children, map);
+ }
+ map.set(node.id, node);
+ });
+ }
+
+ public addConnection(sourceId: string, targetId: string) {
+ const node = this.getNodeMap().get(sourceId);
+ if (node) {
+ const index = node.connection.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId);
+ if (index === -1) {
+ const sequenceFlow: SequenceFlow = { sourceRef: sourceId, targetRef: targetId };
+ node.connection.push(sequenceFlow);
+ }
+ }
+ }
+
+ public deleteConnection(sourceId: string, targetId: string) {
+ const node = this.getNodeMap().get(sourceId);
+ if (node) {
+ const index = node.connection.findIndex(sequenceFlow => sequenceFlow.targetRef === targetId);
+ if (index !== -1) {
+ node.connection.splice(index, 1);
+ }
+ }
+ }
+
+ public deleteNode(parentId: string, nodeId: string): WorkflowNode {
+ const nodeMap = this.getNodeMap();
+
+ const nodes = this.getChildrenNodes(parentId);
+
+ // delete related connections
+ nodes.forEach(node => this.deleteConnection(node.id, nodeId));
+
+ // delete current node
+ const index = nodes.findIndex(node => node.id === nodeId);
+ if (index !== -1) {
+ const node = nodes.splice(index, 1)[0];
+ node.connection = [];
+ return node;
+ }
+
+ return null;
+ }
+
+ public addChild(parentId: string, child: WorkflowNode) {
+ this.getChildrenNodes(parentId).push(child);
+ }
+
+ public deleteChild(node: SubProcess, id: string): WorkflowNode {
+ const index = node.children.findIndex(child => child.id === id);
+ if (index !== -1) {
+ const deletedNode = node.children.splice(index, 1);
+ return deletedNode[0];
+ }
+
+ return null;
+ }
+
+ public getPlanParameters(nodeId: string): PlanTreeviewItem[] {
+ const preNodeList = new Array<WorkflowNode>();
+ this.getPreNodes(nodeId, this.getNodeMap(), preNodeList);
+
+ return this.loadNodeOutputs(preNodeList);
+ }
+
+ private loadNodeOutputs(nodes: WorkflowNode[]): PlanTreeviewItem[] {
+ const params = new Array<PlanTreeviewItem>();
+ nodes.forEach(node => {
+ switch (node.type) {
+ case NodeType[NodeType.startEvent]:
+ params.push(this.loadOutput4StartEvent(<StartEvent>node));
+ break;
+ case NodeType[NodeType.toscaNodeManagementTask]:
+ params.push(this.loadOutput4ToscaNodeTask(<ToscaNodeTask>node));
+ break;
+ case NodeType[NodeType.restTask]:
+ params.push(this.loadOutput4RestTask(<RestTask>node));
+ break;
+ default:
+ break;
+ }
+ });
+
+ return params;
+ }
+
+ private loadOutput4StartEvent(node: StartEvent): PlanTreeviewItem {
+ const startItem = new PlanTreeviewItem(node.name, `[${node.id}]`, [], false);
+ node.parameters.map(param =>
+ startItem.children.push(new PlanTreeviewItem(param.name, `[${param.name}]`, [])));
+ return startItem;
+ }
+
+ private loadOutput4ToscaNodeTask(node: ToscaNodeTask): PlanTreeviewItem {
+ const item = new PlanTreeviewItem(node.name, `[${node.id}]`, [], false);
+ item.children.push(this.createStatusCodeTreeViewItem(node.id));
+ const responseItem = this.createResponseTreeViewItem(node.id);
+ item.children.push(responseItem);
+
+ node.output.map(param =>
+ responseItem.children.push(new PlanTreeviewItem(param.name, `${responseItem.value}.[${param.name}]`, [])));
+ return item;
+ }
+
+ private loadOutput4RestTask(node: RestTask): PlanTreeviewItem {
+ const item = new PlanTreeviewItem(node.name, `[${node.id}]`, [], false);
+ item.children.push(this.createStatusCodeTreeViewItem(node.id));
+
+ if (node.responses.length !== 0) { // load rest responses
+ const responseItem = this.createResponseTreeViewItem(node.id);
+ item.children.push(responseItem);
+ // todo: should list all available response or only the first one?
+ if (node.responses[0]) {
+ const swagger = this.restService.getSwaggerInfo(node.restConfigId);
+ const SwaggerReferenceObject = node.responses[0].schema as SwaggerReferenceObject;
+ const swaggerDefinition = this.restService.getDefinition(swagger, SwaggerReferenceObject.$ref);
+ this.loadParamsBySwaggerDefinition(responseItem, swagger, swaggerDefinition);
+ }
+ }
+
+ return item;
+ }
+
+ private loadParamsBySwaggerDefinition(parentItem: PlanTreeviewItem, swagger: Swagger, definition: any) {
+ Object.getOwnPropertyNames(definition.properties).map(key => {
+ const property = definition.properties[key];
+ const value = `${parentItem.value}.[${key}]`;
+ const propertyItem = new PlanTreeviewItem(key, value, []);
+ parentItem.children.push(propertyItem);
+
+ // reference to swagger.ts function getSchemaObject()
+ if (property instanceof SwaggerReferenceObject) {
+ // handle reference parameter.
+ const propertyDefinition = this.restService.getDefinition(swagger, property.$ref);
+ this.loadParamsBySwaggerDefinition(propertyItem, swagger, propertyDefinition);
+ } else if (property instanceof SwaggerModelSimple) {
+ // handle object parameter.
+ this.loadParamsBySwaggerDefinition(propertyItem, swagger, property);
+ } else {
+ // skip
+ }
+
+ return propertyItem;
+ });
+ }
+
+ private createStatusCodeTreeViewItem(nodeId: string): PlanTreeviewItem {
+ return new PlanTreeviewItem('statusCode', `[${nodeId}].[statusCode]`, []);
+ }
+
+ private createResponseTreeViewItem(nodeId: string): PlanTreeviewItem {
+ return new PlanTreeviewItem('response', `[${nodeId}].[responseBody]`, []);
+ }
+
+ public getPreNodes(nodeId: string, nodeMap: Map<string, WorkflowNode>, preNodes: WorkflowNode[]) {
+ const preNode4CurrentNode = [];
+ nodeMap.forEach(node => {
+ if (this.isPreNode(node, nodeId)) {
+ const existNode = preNodes.find(tmpNode => tmpNode.id === node.id);
+ if (existNode) {
+ // current node already exists. this could avoid loop circle.
+ } else {
+ preNode4CurrentNode.push(node);
+ preNodes.push(node);
+ }
+ }
+ });
+
+ preNode4CurrentNode.forEach(node => this.getPreNodes(node.id, nodeMap, preNodes));
+ }
+
+ public isPreNode(preNode: WorkflowNode, id: string): boolean {
+ const targetNode = preNode.connection.find(connection => connection.targetRef === id);
+ return targetNode !== undefined;
+ }
+
+ public save() {
+ console.log('****************** save data *********************');
+ console.log(this.planModel);
+
+ this.broadcastService.broadcast(this.broadcastService.saveEvent, this.planModel);
+ }
+
+ private createId() {
+ const nodeMap = this.getNodeMap();
+
+ for (let i = 0; i < nodeMap.size; i++) {
+ const key = 'node' + i;
+ if (!nodeMap.get(key)) {
+ return key;
+ }
+ }
+
+ return 'node' + nodeMap.size;
+ }
+}
diff --git a/sdc-workflow-designer-ui/src/app/services/rest.service.ts b/sdc-workflow-designer-ui/src/app/services/rest.service.ts
index 52bddfe3..1db51471 100644
--- a/sdc-workflow-designer-ui/src/app/services/rest.service.ts
+++ b/sdc-workflow-designer-ui/src/app/services/rest.service.ts
@@ -27,32 +27,48 @@ import { NoticeService } from './notice.service';
export class RestService {
private restConfigs: RestConfig[] = [];
- private runtimeURL = '/openoapi/catalog/v1/sys/config';
- private msbPublishServiceURL = '/api/msdiscover/v1/publishservicelist';
+ // private runtimeURL = '/openoapi/catalog/v1/sys/config';
+ private runtimeURL = '/api/tenant';
+ // private msbPublishServiceURL = '/api/msdiscover/v1/publishservicelist';
+ private msbPublishServiceURL = '/api/mockarray';
constructor(private broadcastService: BroadcastService, private http: Http, private noticeService: NoticeService) {
this.broadcastService.planModel$.subscribe(planModel => {
planModel.configs.restConfigs.forEach(element => {
- this.restConfigs.push(element);
+ this.addRestConfig(element);
});
});
- // this.initSwaggerInfoByMSB();
+ this.initSwaggerInfoByMSB();
}
- public addRestConfig(): RestConfig {
- let index = 0;
- this.restConfigs.forEach(config => {
- const currentId = parseInt(config.id);
- if (currentId > index) {
- index = currentId;
- }
+ public addRestConfig(config: RestConfig) {
+ const idSet = new Set<string>();
+ this.restConfigs.forEach(rc => {
+ idSet.add(rc.id);
});
- index += 1;
+ if(idSet.has(config.id)) {
+ return false;
+ } else {
+ this.restConfigs.push(config);
+ return true;
+ }
+ }
- const restConfig = new RestConfig(index.toString(), 'new Config', '', '', '');
- this.restConfigs.push(restConfig);
+ public newRestConfig(): RestConfig {
+ const idSet = new Set<string>();
+ this.restConfigs.forEach(rc => {
+ idSet.add(rc.id);
+ });
+ let index = 0;
+ for(; index <= idSet.size; index++) {
+ if(!idSet.has(index + '')) {
+ break;
+ }
+ }
+
+ const restConfig = new RestConfig(index.toString(), 'new Config', '', '', '');
return restConfig;
}
@@ -125,7 +141,7 @@ export class RestService {
// this service don't have sawgger file.
if ('/activiti-rest' !== serviceInfo.publish_url) {
const id = serviceInfo.serviceName + '.' + serviceInfo.version;
- restConfigs.push(new RestConfig(id, serviceInfo.serviceName, serviceInfo.version, serviceInfo.publish_url, ''));
+ this.addRestConfig(new RestConfig(id, serviceInfo.serviceName, serviceInfo.version, serviceInfo.publish_url, ''));
let swaggerUrl = '';
if (undefined !== serviceInfo.swagger_url && '' !== serviceInfo.swagger_url) {
swaggerUrl = serviceInfo.publish_url + '/' + serviceInfo.swagger_url;