From bb91af99ee72160a29ffd84c3c5a0c65326c1209 Mon Sep 17 00:00:00 2001 From: Lvbo163 Date: Tue, 12 Sep 2017 21:09:38 +0800 Subject: support drag muilt element support select multi element by mouse drag and drag multi element. Issue-ID: SDC-316 Change-Id: I7111b705f2e490b84f030fc4832217808c3783dc Signed-off-by: Lvbo163 --- sdc-workflow-designer-ui/src/app/app.module.ts | 2 + .../app/components/canvas/canvas.component.html | 2 +- .../directive/drag-select/drag-select.directive.ts | 134 +++++++++++++++++++++ .../services/data-access/in-memory-data.service.ts | 3 +- sdc-workflow-designer-ui/src/styles.css | 6 + 5 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 sdc-workflow-designer-ui/src/app/directive/drag-select/drag-select.directive.ts diff --git a/sdc-workflow-designer-ui/src/app/app.module.ts b/sdc-workflow-designer-ui/src/app/app.module.ts index 55b57953..b2bcb742 100644 --- a/sdc-workflow-designer-ui/src/app/app.module.ts +++ b/sdc-workflow-designer-ui/src/app/app.module.ts @@ -46,11 +46,13 @@ import { WorkflowProcessService } from "./services/workflow-process.service"; import { IntermediateCatchEventComponent } from "./components/property/intermediate-catch-event/intermediate-catch-event.component"; import { SequenceFlowComponent } from "./components/sequence-flow/sequence-flow.component"; import { ScriptTaskComponent } from "./components/property/script-task/script-task.component"; +import { DragSelectDirective } from "./directive/drag-select/drag-select.directive"; @NgModule({ declarations: [ AppComponent, CanvasComponent, + DragSelectDirective, EditablePropertyComponent, IntermediateCatchEventComponent, MenuComponent, diff --git a/sdc-workflow-designer-ui/src/app/components/canvas/canvas.component.html b/sdc-workflow-designer-ui/src/app/components/canvas/canvas.component.html index 97fe3a67..daf26bc1 100644 --- a/sdc-workflow-designer-ui/src/app/components/canvas/canvas.component.html +++ b/sdc-workflow-designer-ui/src/app/components/canvas/canvas.component.html @@ -11,6 +11,6 @@ * ZTE - initial API and implementation and/or initial documentation */ --> -
+
diff --git a/sdc-workflow-designer-ui/src/app/directive/drag-select/drag-select.directive.ts b/sdc-workflow-designer-ui/src/app/directive/drag-select/drag-select.directive.ts new file mode 100644 index 00000000..395cf040 --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/directive/drag-select/drag-select.directive.ts @@ -0,0 +1,134 @@ +/** + * 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 { AfterViewInit, Directive, ElementRef } from '@angular/core'; +import { JsPlumbService } from "../../services/jsplumb.service"; + +@Directive({ + selector: '[b4tDragSelect]' +}) +export class DragSelectDirective implements AfterViewInit { + private selectBox: any; + public selecting = false; + + public relatvieX: number; + public relatvieY: number; + + public startX: number; + public startY: number; + public endX: number; + public endY: number; + + public left: number = 0; + public top: number = 0; + public width: number = 0; + public height: number = 0; + + constructor(private el: ElementRef, private jsPlumbService: JsPlumbService) { } + + public ngAfterViewInit(): void { + this.selectBox = document.createElement('div'); + const selectArea = this.el.nativeElement.appendChild(this.selectBox); + this.el.nativeElement.addEventListener("mousedown", (event: MouseEvent) => this.mouseDown(event)); + this.el.nativeElement.addEventListener("mousemove", (event: MouseEvent) => this.mouseMove(event)); + this.el.nativeElement.addEventListener("mouseup", (event: MouseEvent) => this.mouseUp(event)); + } + + public mouseDown(event: MouseEvent) { + this.relatvieX = event.clientX - event.offsetX; + this.relatvieY = event.clientY - event.offsetY; + + this.width = 0; + this.height = 0; + this.startX = event.clientX; + this.startY = event.clientY; + this.endX = this.startX; + this.endY = this.startY; + this.selecting = true; + this.updateSelectArea(); + } + + public mouseMove(event: MouseEvent) { + this.endX = event.clientX; + this.endY = event.clientY; + + this.updateSelectArea(); + } + + public mouseUp(event: MouseEvent) { + this.selecting = false; + this.updateSelectArea(); + } + + private updateSelectArea() { + if (this.selecting) { + this.selectBox.className = 'selecting'; + } else { + this.selectBox.className = ''; + return; + } + + this.getAllSelectedNodes(); + + const leftTmp = this.startX >= this.endX ? this.endX : this.startX; + const topTmp = this.startY >= this.endY ? this.endY : this.startY; + + this.left = leftTmp - this.relatvieX; + this.top = topTmp - this.relatvieY; + + this.width = Math.abs(this.startX - this.endX); + this.height = Math.abs(this.endY - this.startY); + + this.selectBox.style.top = this.top + 'px'; + this.selectBox.style.left = this.left + 'px'; + this.selectBox.style.width = this.width + 'px'; + this.selectBox.style.height = this.height + 'px'; + } + + public getAllSelectedNodes() { + if(!this.selecting) { + return; + } + const selectedNodes = []; + + const nodes = this.el.nativeElement.querySelectorAll('div.node'); + nodes.forEach(node => { + if(this.checkNodeSelected(node)) { + selectedNodes.push(node); + } + }); + + this.jsPlumbService.jsplumbInstance.clearDragSelection(); + this.jsPlumbService.jsplumbInstance.addToDragSelection(selectedNodes); + + } + + private checkNodeSelected(node: any): boolean { + const nodeLeft = node.offsetLeft; + const nodeTop = node.offsetTop; + const nodeRigth = nodeLeft + node.clientWidth; + const nodeBottom = nodeTop + node.clientHeight; + + const selectedRight = this.left + this.width; + const selectedBottom = this.top + this.height; + + return this.between(nodeLeft, this.left, selectedRight) + && this.between(nodeRigth, this.left, selectedRight) + && this.between(nodeTop, this.top, selectedBottom) + && this.between(nodeBottom, this.top, selectedBottom); + } + + private between(value, min, max): boolean { + return min <= value && value <= max; + } + +} diff --git a/sdc-workflow-designer-ui/src/app/services/data-access/in-memory-data.service.ts b/sdc-workflow-designer-ui/src/app/services/data-access/in-memory-data.service.ts index 0ad5face..efc1e0b5 100644 --- a/sdc-workflow-designer-ui/src/app/services/data-access/in-memory-data.service.ts +++ b/sdc-workflow-designer-ui/src/app/services/data-access/in-memory-data.service.ts @@ -40,7 +40,8 @@ export class InMemoryDataService implements InMemoryDbService { configs: { microservices: [] } - } + }, + {"id":"fjh","name":"fjh","nodes":[{"id":"node0","name":"startEvent","type":"startEvent","position":{"top":43,"left":80.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node0","targetRef":"node2"}],"parameters":[]},{"id":"node1","name":"endEvent","type":"endEvent","position":{"top":273,"left":488,"width":200,"height":100},"sequenceFlows":[]},{"id":"node2","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":6,"left":178,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node2","targetRef":"node3","condition":"未完成"},{"sourceRef":"node2","targetRef":"node4","condition":"创建完成"}]},{"id":"node3","name":"createVL","type":"restTask","position":{"top":13.5,"left":283.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node3","targetRef":"node11"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node4","name":"restTask","type":"restTask","position":{"top":110,"left":152,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node4","targetRef":"node5"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node5","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":27.5,"left":401.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node5","targetRef":"node6","condition":"未完成"},{"sourceRef":"node5","targetRef":"node12","condition":"创建完成"}]},{"id":"node6","name":"createVNF","type":"restTask","position":{"top":91,"left":389,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node6","targetRef":"node7"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node7","name":"intermediateCatchEvent","type":"intermediateCatchEvent","position":{"top":190.5,"left":398,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node7","targetRef":"node8"}],"timerEventDefinition":{"type":"timeDuration"}},{"id":"node8","name":"query_vnf nslcm","type":"restTask","position":{"top":240,"left":390,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node8","targetRef":"node9"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node9","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":316.5,"left":405.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node9","targetRef":"node7","condition":"未完成"},{"sourceRef":"node9","targetRef":"node10","condition":"已完成"}]},{"id":"node10","name":"scriptTask","type":"scriptTask","position":{"top":405.5,"left":404.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node10","targetRef":"node5"}]},{"id":"node11","name":"scriptTask","type":"scriptTask","position":{"top":181.5,"left":110.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node11","targetRef":"node2"}]},{"id":"node12","name":"restTask","type":"restTask","position":{"top":147.5,"left":364.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node12","targetRef":"node13"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node13","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":214.5,"left":397.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node13","targetRef":"node14","condition":"未结束"},{"sourceRef":"node13","targetRef":"node18","condition":"已结束"}]},{"id":"node14","name":"createSfc","type":"restTask","position":{"top":202,"left":290.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node14","targetRef":"node15"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node15","name":"intermediateCatchEvent","type":"intermediateCatchEvent","position":{"top":128,"left":145.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node15","targetRef":"node16"}],"timerEventDefinition":{"type":"timeDuration"}},{"id":"node16","name":"restTask","type":"restTask","position":{"top":330.5,"left":221,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node16","targetRef":"node17"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node17","name":"exclusiveGateway","type":"exclusiveGateway","position":{"top":402,"left":351.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node17","targetRef":"node15","condition":"未结束"},{"sourceRef":"node17","targetRef":"node19","condition":"已结束"}]},{"id":"node18","name":"restTask","type":"restTask","position":{"top":217.5,"left":194,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node18","targetRef":"node20"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node19","name":"scriptTask","type":"scriptTask","position":{"top":466,"left":389,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node19","targetRef":"node13"}]},{"id":"node20","name":"Assign_all_status","type":"scriptTask","position":{"top":306.5,"left":590.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node20","targetRef":"node21"}]},{"id":"node21","name":"post_do","type":"restTask","position":{"top":390,"left":612.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node21","targetRef":"node22"}],"produces":[],"consumes":[],"parameters":[],"responses":[]},{"id":"node22","name":"jobstatus","type":"restTask","position":{"top":426,"left":682.5,"width":200,"height":100},"sequenceFlows":[{"sourceRef":"node22","targetRef":"node1"}],"produces":[],"consumes":[],"parameters":[],"responses":[]}],"configs":{"microservices":[]}}, ]; return { workflows, swagger}; } diff --git a/sdc-workflow-designer-ui/src/styles.css b/sdc-workflow-designer-ui/src/styles.css index 6b32fc30..0a624d5e 100644 --- a/sdc-workflow-designer-ui/src/styles.css +++ b/sdc-workflow-designer-ui/src/styles.css @@ -57,3 +57,9 @@ textarea.form-control { margin: 0 !important; font-size: 12px !important; } + +.selecting { + border: 1px solid royalblue; + background-color: yellowgreen; + position: absolute; +} -- cgit 1.2.3-korg