Skip to content

Commit

Permalink
fix(modeling): attach shapes with labels on paste
Browse files Browse the repository at this point in the history
Closes #1204
  • Loading branch information
Oguz Eroglu authored and barmac committed Oct 7, 2019
1 parent 06a8a2c commit 69881bd
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 61 deletions.
26 changes: 20 additions & 6 deletions lib/features/modeling/behavior/CreateBoundaryEventBehavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import inherits from 'inherits';

import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';

import { is } from '../../../util/ModelUtil';

import { isAny } from '../util/ModelingUtil';
import { isLabel } from '../../../util/LabelUtil';

/**
* BPMN specific create boundary event behavior
*/
export default function CreateBoundaryEventBehavior(
eventBus, modeling, elementFactory,
bpmnFactory) {
bpmnFactory, moddleCopy) {

CommandInterceptor.call(this, eventBus);

Expand All @@ -25,21 +25,34 @@ export default function CreateBoundaryEventBehavior(
businessObject,
boundaryEvent;

if (isLabel(shape)) {
return;
}

var attrs = {
cancelActivity: true
};

if (host && is(shape, 'bpmn:IntermediateThrowEvent')) {
if (host && isAny(shape, [ 'bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent' ])) {
attrs.attachedToRef = host.businessObject;

businessObject = bpmnFactory.create('bpmn:BoundaryEvent', attrs);

moddleCopy.copyElement(shape.businessObject, businessObject);

boundaryEvent = {
type: 'bpmn:BoundaryEvent',
businessObject: businessObject
};

context.shape = elementFactory.createShape(boundaryEvent);
var newShape = elementFactory.createShape(boundaryEvent);
context.shape.labels.forEach(function(label) {
newShape.labels.add(label);
label.labelTarget = newShape;
label.businessObject = newShape.businessObject;
});

context.shape = newShape;
}
}, true);
}
Expand All @@ -48,7 +61,8 @@ CreateBoundaryEventBehavior.$inject = [
'eventBus',
'modeling',
'elementFactory',
'bpmnFactory'
'bpmnFactory',
'moddleCopy'
];

inherits(CreateBoundaryEventBehavior, CommandInterceptor);
14 changes: 13 additions & 1 deletion lib/features/snapping/BpmnCreateMoveSnapping.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,18 @@ function snapBoundaryEvent(event, target) {
if (/right/.test(direction)) {
setSnapped(event, 'x', targetTRBL.right);
}

if (event.elements && event.elements.length > 1) {
var element = event.elements[0];
if (event.snapped.x || event.snapped.y) {
var corrX = element.x + (element.width / 2);
var corrY = element.y + (element.height / 2);
event.x -= corrX;
event.y -= corrY;
event.dx -= corrX;
event.dy -= corrY;
}
}
}

function areAll(elements, type) {
Expand Down Expand Up @@ -225,4 +237,4 @@ function setSnappedIfConstrained(event) {

function includes(array, value) {
return array.indexOf(value) !== -1;
}
}
201 changes: 147 additions & 54 deletions test/spec/features/snapping/BpmnCreateMoveSnappingSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,87 +155,180 @@ describe('features/snapping - BpmnCreateMoveSnapping', function() {

var task, taskGfx, intermediateThrowEvent;

beforeEach(inject(function(create, dragging, elementRegistry, elementFactory) {
task = elementRegistry.get('Task_1');
taskGfx = elementRegistry.getGraphics(task);
describe('without label', function() {

intermediateThrowEvent = elementFactory.createShape({
type: 'bpmn:IntermediateThrowEvent'
});
beforeEach(inject(function(create, dragging, elementRegistry, elementFactory) {
task = elementRegistry.get('Task_1');
taskGfx = elementRegistry.getGraphics(task);

create.start(canvasEvent({ x: 0, y: 0 }), intermediateThrowEvent);
intermediateThrowEvent = elementFactory.createShape({
type: 'bpmn:IntermediateThrowEvent'
});

dragging.hover({ element: task, gfx: taskGfx });
}));
create.start(canvasEvent({ x: 0, y: 0 }), intermediateThrowEvent);

dragging.hover({ element: task, gfx: taskGfx });
}));

it('should snap to top', inject(function(dragging) {

// when
dragging.move(canvasEvent({ x: 150, y: 95 }));
it('should snap to top', inject(function(dragging) {

dragging.end();
// when
dragging.move(canvasEvent({ x: 150, y: 95 }));

// then
var boundaryEvent = getBoundaryEvent(task);
dragging.end();

expect(mid(boundaryEvent)).to.eql({
x: 150,
y: 100 // 95 snapped to 100
});
}));
// then
var boundaryEvent = getBoundaryEvent(task);

expect(mid(boundaryEvent)).to.eql({
x: 150,
y: 100 // 95 snapped to 100
});
}));

it('should snap to right', inject(function(dragging) {

// when
dragging.move(canvasEvent({ x: 195, y: 140 }));
it('should snap to right', inject(function(dragging) {

dragging.end();
// when
dragging.move(canvasEvent({ x: 195, y: 140 }));

// then
var boundaryEvent = getBoundaryEvent(task);
dragging.end();

expect(mid(boundaryEvent)).to.eql({
x: 200, // 195 snapped to 200
y: 140
});
}));
// then
var boundaryEvent = getBoundaryEvent(task);

expect(mid(boundaryEvent)).to.eql({
x: 200, // 195 snapped to 200
y: 140
});
}));

it('should snap to bottom', inject(function(dragging) {

// when
dragging.move(canvasEvent({ x: 150, y: 175 }));
it('should snap to bottom', inject(function(dragging) {

dragging.end();
// when
dragging.move(canvasEvent({ x: 150, y: 175 }));

// then
var boundaryEvent = getBoundaryEvent(task);
dragging.end();

expect(mid(boundaryEvent)).to.eql({
x: 150,
y: 180 // 175 snapped to 180
});
}));
// then
var boundaryEvent = getBoundaryEvent(task);

expect(mid(boundaryEvent)).to.eql({
x: 150,
y: 180 // 175 snapped to 180
});
}));

it('should snap to left', inject(function(dragging) {

// when
dragging.move(canvasEvent({ x: 95, y: 140 }));
it('should snap to left', inject(function(dragging) {

dragging.end();
// when
dragging.move(canvasEvent({ x: 95, y: 140 }));

// then
var boundaryEvent = getBoundaryEvent(task);
dragging.end();

expect(mid(boundaryEvent)).to.eql({
x: 100, // 95 snapped to 100
y: 140
});
}));
// then
var boundaryEvent = getBoundaryEvent(task);

expect(mid(boundaryEvent)).to.eql({
x: 100, // 95 snapped to 100
y: 140
});
}));
});


describe('with label', function() {

beforeEach(inject(function(create, dragging, elementRegistry, elementFactory) {
task = elementRegistry.get('Task_1');
taskGfx = elementRegistry.getGraphics(task);

intermediateThrowEvent = elementFactory.createShape({
type: 'bpmn:IntermediateThrowEvent'
});
var label = elementFactory.createLabel({
labelTarget: intermediateThrowEvent,
y: 50,
width: intermediateThrowEvent.width,
height: intermediateThrowEvent.height / 4
});

create.start(canvasEvent({ x: 0, y: 0 }), [ intermediateThrowEvent, label ]);

dragging.hover({ element: task, gfx: taskGfx });
}));


it('should snap to topLeft', inject(function(dragging) {

// when
dragging.move(canvasEvent({ x: 90, y: 95 }));

dragging.end();

// then
var boundaryEvent = getBoundaryEvent(task);

expect(mid(boundaryEvent)).to.eql({
x: 100, // 90 snapped to 100
y: 100 // 95 snapped to 100
});
}));


it('should snap to topRight', inject(function(dragging) {

// when
dragging.move(canvasEvent({ x: 210, y: 95 }));

dragging.end();

// then
var boundaryEvent = getBoundaryEvent(task);

expect(mid(boundaryEvent)).to.eql({
x: 200, // 210 snapped to 200
y: 100 // 95 snapped to 100
});
}));


it('should snap to bottomLeft', inject(function(dragging) {

// when
dragging.move(canvasEvent({ x: 90, y: 190 }));

dragging.end();

// then
var boundaryEvent = getBoundaryEvent(task);

expect(mid(boundaryEvent)).to.eql({
x: 100, // 90 snapped to 100
y: 180 // 190 snapped to 180
});
}));


it('should snap to bottomRight', inject(function(dragging) {

// when
dragging.move(canvasEvent({ x: 210, y: 190 }));

dragging.end();

// then
var boundaryEvent = getBoundaryEvent(task);

expect(mid(boundaryEvent)).to.eql({
x: 200, // 210 snapped to 200
y: 180 // 190 snapped to 180
});
}));
});
});


Expand Down Expand Up @@ -562,4 +655,4 @@ function canvasEventTopLeft(position, shape) {

function getBoundaryEvent(element) {
return element.attachers[0];
}
}

0 comments on commit 69881bd

Please sign in to comment.