Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions lib/features/modeling/BpmnUpdater.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,50 @@ export default function BpmnUpdater(
}
});

// Handles artifacts on participants
eventBus.on('shape.move.start', function(event) {
let shape = event.shape;

if (!is(shape, 'bpmn:Participant')) {
return;
}

let parent = shape.parent,
context = event.context,
possibleParticipants = parent.children.filter(child => is(child, 'bpmn:Participant')),
possibleArtifacts = parent.children.filter(child => is(child, 'bpmn:Artifact'));

forEach(possibleArtifacts, function(currentShape) {
let participantCounter = 0,
curOverlap = calculateOverlappingArea(shape, currentShape);

if (isAssociatedTextAnnotation (currentShape, possibleParticipants)) {
context.shapes.push(currentShape);
return;
}

if (curOverlap <= 0) {
return;
}
possibleParticipants.forEach(function(participant) {

if (participantCounter >= 2) {
return;
}

participantCounter = calculateOverlappingArea(currentShape, participant) === (currentShape.height * currentShape.width) ? participantCounter + 1 : participantCounter;
});

if (participantCounter === 1) {
context.shapes.push(currentShape);
}


});

});


// attach / detach connection
function updateConnection(e) {
self.updateConnection(e.context);
Expand Down Expand Up @@ -816,4 +860,42 @@ function getEmbeddedLabelBounds(shape) {
}

return label.get('bounds');
}

function calculateOverlappingArea(child, possibleParent) {
const leftA = child.x;
const rightA = child.x + child.width;
const topA = child.y;
const bottomA = child.y + child.height;

const leftB = possibleParent.x;
const rightB = possibleParent.x + possibleParent.width;
const topB = possibleParent.y;
const bottomB = possibleParent.y + possibleParent.height;

const overlapWidth = Math.max(0, Math.min(rightA, rightB) - Math.max(leftA, leftB));
const overlapHeight = Math.max(0, Math.min(bottomA, bottomB) - Math.max(topA, topB));

return overlapWidth * overlapHeight;
}

function isAssociatedTextAnnotation(shape, possibleParticipants) {
if (shape.type !== 'bpmn:TextAnnotation') {
return false;
}
let possibleAssociatedElements = possibleParticipants.flatMap((participant) => participant.children).flatMap((element) => element.id),
incomingElements = shape.incoming.flatMap((shape) => shape.businessObject.sourceRef.id),
isAssociated = false;


incomingElements.forEach((associatedElement) => {
possibleAssociatedElements.forEach(possibleElement => {
if (isAssociated) {
return;
}
isAssociated = associatedElement === possibleElement;
});
});
return isAssociated;

}
31 changes: 31 additions & 0 deletions test/fixtures/bpmn/participant-with-one-artifact.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1jlhm18" targetNamespace="http://bpmn.io/schema/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="18.6.1">
<bpmn:collaboration id="Collaboration_14pprp4">
<bpmn:participant id="Participant_1axg5jz" processRef="Process_18wyzo7" />
<bpmn:textAnnotation id="TextAnnotation_0hsrpnp">
<bpmn:text>test</bpmn:text>
</bpmn:textAnnotation>
<bpmn:association id="Association_1et62da" associationDirection="None" sourceRef="StartEvent_09y0l4d" targetRef="TextAnnotation_0hsrpnp" />
</bpmn:collaboration>
<bpmn:process id="Process_18wyzo7" isExecutable="false">
<bpmn:startEvent id="StartEvent_09y0l4d" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_14pprp4">
<bpmndi:BPMNShape id="Participant_1axg5jz_di" bpmnElement="Participant_1axg5jz" isHorizontal="true">
<dc:Bounds x="160" y="80" width="600" height="250" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_09y0l4d">
<dc:Bounds x="342" y="182" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Association_1et62da_di" bpmnElement="Association_1et62da">
<di:waypoint x="371" y="186" />
<di:waypoint x="418" y="130" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="TextAnnotation_0hsrpnp_di" bpmnElement="TextAnnotation_0hsrpnp">
<dc:Bounds x="380" y="100" width="100" height="30" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
42 changes: 42 additions & 0 deletions test/fixtures/bpmn/participant-with-one-group.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1jlhm18" targetNamespace="http://bpmn.io/schema/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="18.6.1">
<bpmn:collaboration id="Collaboration_14pprp4">
<bpmn:participant id="Participant_1axg5jz" processRef="Process_18wyzo7" />
<bpmn:group id="Group_0rfu791" categoryValueRef="CategoryValue_1nf9na9" />
</bpmn:collaboration>
<bpmn:process id="Process_18wyzo7" isExecutable="false">
<bpmn:startEvent id="StartEvent_09y0l4d">
<bpmn:outgoing>Flow_0vdmipo</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:endEvent id="Event_151nhg7">
<bpmn:incoming>Flow_0vdmipo</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0vdmipo" sourceRef="StartEvent_09y0l4d" targetRef="Event_151nhg7" />
</bpmn:process>
<bpmn:category id="Category_0d3jxnq">
<bpmn:categoryValue id="CategoryValue_1nf9na9" value="important" />
</bpmn:category>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_14pprp4">
<bpmndi:BPMNShape id="Participant_1axg5jz_di" bpmnElement="Participant_1axg5jz" isHorizontal="true">
<dc:Bounds x="160" y="80" width="600" height="250" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_09y0l4d">
<dc:Bounds x="342" y="182" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_151nhg7_di" bpmnElement="Event_151nhg7">
<dc:Bounds x="562" y="182" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0vdmipo_di" bpmnElement="Flow_0vdmipo">
<di:waypoint x="378" y="200" />
<di:waypoint x="562" y="200" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Group_0rfu791_di" bpmnElement="Group_0rfu791">
<dc:Bounds x="310" y="130" width="310" height="140" />
<bpmndi:BPMNLabel>
<dc:Bounds x="442" y="137" width="47" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
33 changes: 33 additions & 0 deletions test/fixtures/bpmn/participants-with-artifact.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_0djjdgr" targetNamespace="http://bpmn.io/schema/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="18.6.1">
<bpmn:collaboration id="Collaboration_0yulavs">
<bpmn:participant id="Participant_09y906w" processRef="Process_10csbrj" />
<bpmn:participant id="Participant_1svjgx6" processRef="Process_024zi7r" />
<bpmn:group id="Group_0007vsj" />
</bpmn:collaboration>
<bpmn:process id="Process_10csbrj" isExecutable="false">
<bpmn:startEvent id="StartEvent_0f4eo5c" />
</bpmn:process>
<bpmn:process id="Process_024zi7r">
<bpmn:endEvent id="Event_0ofrct3" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_0yulavs">
<bpmndi:BPMNShape id="Participant_09y906w_di" bpmnElement="Participant_09y906w" isHorizontal="true">
<dc:Bounds x="166" y="80" width="600" height="250" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_0f4eo5c">
<dc:Bounds x="422" y="172" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Participant_1svjgx6_di" bpmnElement="Participant_1svjgx6" isHorizontal="true">
<dc:Bounds x="160" y="540" width="600" height="250" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0ofrct3_di" bpmnElement="Event_0ofrct3">
<dc:Bounds x="422" y="632" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Group_0007vsj_di" bpmnElement="Group_0007vsj">
<dc:Bounds x="290" y="130" width="300" height="590" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
128 changes: 127 additions & 1 deletion test/spec/ModelerSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
setBpmnJS,
clearBpmnJS,
collectTranslations,
enableLogging
enableLogging, bootstrapModeler
} from 'test/TestHelper';

import {
Expand All @@ -27,6 +27,12 @@ import {
} from 'min-dash';

import { getDi } from 'lib/util/ModelUtil';
import diagramXML from './features/grid-snapping/basic.bpmn';
import coreModule from '../../lib/core';
import createModule from 'diagram-js/lib/features/create';
import gridSnappingModule from '../../lib/features/grid-snapping';
import modelingModule from '../../lib/features/modeling';
import moveModule from 'diagram-js/lib/features/move';


var singleStart = window.__env__ && window.__env__.SINGLE_START === 'modeler';
Expand Down Expand Up @@ -947,6 +953,126 @@ describe('Modeler', function() {

});

describe('artifacts move with their participants', function() {

beforeEach(bootstrapModeler(diagramXML, {
modules: [
coreModule,
createModule,
gridSnappingModule,
modelingModule,
moveModule
]
}));


it('should drag participant and annotation should follow', async function() {
var xml = require('../fixtures/bpmn/participant-with-one-artifact.bpmn');

const result = await createModeler(xml);
expect(result.error).not.to.exist;

var modeler = result.modeler;
var elementRegistry = modeler.get('elementRegistry');
var dragging = modeler.get('dragging');
var move = modeler.get('move');

var participant = elementRegistry.get('Participant_1axg5jz');
var annotation = elementRegistry.get('TextAnnotation_0hsrpnp');

expect(participant).to.exist;
expect(annotation).to.exist;

const oldX = annotation.x;
const oldY = annotation.y;

move.start(
createCanvasEvent({ x: participant.x + 10, y: participant.y + 10 }),
participant
);

dragging.move(createCanvasEvent({ x: participant.x + 110, y: participant.y + 60 }));

dragging.end();

const newAnnotation = elementRegistry.get('TextAnnotation_0hsrpnp');

expect(newAnnotation.x).to.equal(oldX + 100);
expect(newAnnotation.y).to.equal(oldY + 50);
});

it('should drag participant and group should follow', async function() {
var xml = require('../fixtures/bpmn/participant-with-one-group.bpmn');

const result = await createModeler(xml);
expect(result.error).not.to.exist;

var modeler = result.modeler;
var elementRegistry = modeler.get('elementRegistry');
var move = modeler.get('move');
var dragging = modeler.get('dragging');

var participant = elementRegistry.get('Participant_1axg5jz');
var group = elementRegistry.get('Group_0rfu791');

expect(participant).to.exist;
expect(group).to.exist;

const oldX = group.x;
const oldY = group.y;

move.start(
createCanvasEvent({ x: participant.x + 20, y: participant.y + 20 }),
participant
);

dragging.move(createCanvasEvent({ x: participant.x + 140, y: participant.y + 80 }));

dragging.end();

const newGroup = elementRegistry.get('Group_0rfu791');

expect(newGroup.x).to.equal(oldX + 120);
expect(newGroup.y).to.equal(oldY + 60);
});

it('should NOT move group when it overlaps two participants and one participant is dragged', async function() {
var xml = require('../fixtures/bpmn/participants-with-artifact.bpmn');

const result = await createModeler(xml);
expect(result.error).not.to.exist;

var modeler = result.modeler;
var elementRegistry = modeler.get('elementRegistry');
var move = modeler.get('move');
var dragging = modeler.get('dragging');

var participant1 = elementRegistry.get('Participant_09y906w');
var participant2 = elementRegistry.get('Participant_1svjgx6');
var group = elementRegistry.get('Group_0007vsj');

expect(participant1).to.exist;
expect(participant2).to.exist;
expect(group).to.exist;

const oldX = group.x;
const oldY = group.y;

console.log(participant1);
move.start(
createCanvasEvent({ x: participant1.x + 20, y: participant1.y + 20 }),
participant1
);

dragging.move(createCanvasEvent({ x: participant1.x + 120, y: participant1.y + 80 }));
dragging.end();

const newGroup = elementRegistry.get('Group_0007vsj');

expect(newGroup.x).to.equal(oldX);
expect(newGroup.y).to.equal(oldY);
});
});
});


Expand Down