diff --git a/lib/features/rules/BpmnRules.js b/lib/features/rules/BpmnRules.js index 079cb277d6..c2df36eb98 100644 --- a/lib/features/rules/BpmnRules.js +++ b/lib/features/rules/BpmnRules.js @@ -144,7 +144,7 @@ BpmnRules.prototype.init = function() { return every(elements, function(element) { if (isConnection(element)) { - return canConnect(element.source, element.target, element); + return (canConnect(element.source, element.target, element) || {}).type === element.type; } if (element.host) { @@ -1068,11 +1068,11 @@ function canConnectMessageFlow(source, target) { return false; } - return ( - isMessageFlowSource(source) && - isMessageFlowTarget(target) && - !isSameOrganization(source, target) - ); + return isMessageFlowSource(source) + && (is(source, 'bpmn:Participant') || !!getParent(source, 'bpmn:Participant')) + && isMessageFlowTarget(target) + && (is(target, 'bpmn:Participant') || !!getParent(target, 'bpmn:Participant')) + && !isSameOrganization(source, target); } /** @@ -1143,16 +1143,6 @@ function canInsert(shape, connection, position) { canDrop(shape, connection.parent, position)); } -/** - * @param {Element[]} elements - * @param {Element} element - * - * @return {boolean} - */ -function includes(elements, element) { - return (elements && element) && elements.indexOf(element) !== -1; -} - /** * @param {Element[]} elements * @param {Element} element @@ -1164,10 +1154,18 @@ function canCopy(elements, element) { return true; } - if (is(element, 'bpmn:Lane') && !includes(elements, element.parent)) { + if (is(element, 'bpmn:Lane') && !elements.includes(element.parent)) { return false; } + if (is(element, 'bpmn:MessageFlow')) { + const source = element.source, + target = element.target; + + return elements.includes(is(source, 'bpmn:Participant') ? source : getParent(source, 'bpmn:Participant')) + && elements.includes(is(target, 'bpmn:Participant') ? target : getParent(target, 'bpmn:Participant')); + } + return true; } @@ -1178,4 +1176,4 @@ function canCopy(elements, element) { */ function getRootElement(element) { return getParent(element, 'bpmn:Process') || getParent(element, 'bpmn:Collaboration'); -} +} \ No newline at end of file diff --git a/test/spec/features/copy-paste/BpmnCopyPasteSpec.js b/test/spec/features/copy-paste/BpmnCopyPasteSpec.js index 165ce05278..444bf39580 100644 --- a/test/spec/features/copy-paste/BpmnCopyPasteSpec.js +++ b/test/spec/features/copy-paste/BpmnCopyPasteSpec.js @@ -964,6 +964,31 @@ describe('features/copy-paste', function() { }); + + describe('rules', function() { + + beforeEach(bootstrapModeler(collaborationMultipleXML, { + modules: testModules, + moddleExtensions: { + camunda: camundaPackage + } + })); + + + it('should allow copying message flow with parent participants of source and target', inject(function(elementRegistry) { + + // when + var tree = copy([ 'IntermediateThrowEvent_1', 'Task_2', 'MessageFlow_1' ]); + + console.log(tree, keys(tree)); + + // then + expect(keys(tree)).to.have.length(1); + expect(getAllElementsInTree(tree, 0)).to.have.length(2); + })); + + }); + }); diff --git a/test/spec/features/rules/BpmnRulesSpec.js b/test/spec/features/rules/BpmnRulesSpec.js index 90c2f3e145..e320f92334 100644 --- a/test/spec/features/rules/BpmnRulesSpec.js +++ b/test/spec/features/rules/BpmnRulesSpec.js @@ -58,7 +58,8 @@ describe('features/modeling/rules - BpmnRules', function() { sequenceFlow = elementFactory.createConnection({ type: 'bpmn:SequenceFlow', source: task1, - target: task2 + target: task2, + waypoints: [] }); // then @@ -74,7 +75,8 @@ describe('features/modeling/rules - BpmnRules', function() { sequenceFlow = elementFactory.createConnection({ type: 'bpmn:MessageFlow', source: task1, - target: task2 + target: task2, + waypoints: [] }); // then @@ -218,6 +220,32 @@ describe('features/modeling/rules - BpmnRules', function() { expectCanCopy(boundaryEvent, [ boundaryEvent ], true); })); + + it('copy message flow with parent participants of source and target', inject(function(elementFactory) { + + // given + var sourceParticipant = elementFactory.createShape({ type: 'bpmn:Participant' }), + targetParticipant = elementFactory.createShape({ type: 'bpmn:Participant' }), + source = elementFactory.createShape({ type: 'bpmn:Task', parent: sourceParticipant }), + target = elementFactory.createShape({ type: 'bpmn:Task', parent: targetParticipant }), + messageFlow = elementFactory.createConnection({ type: 'bpmn:MessageFlow', source: source, target: target, waypoints: [] }); + + // then + expectCanCopy(messageFlow, [ sourceParticipant, targetParticipant, source, target, messageFlow ], true); + })); + + + it('copy message flow without parent participants of source and target', inject(function(elementFactory) { + + // given + var source = elementFactory.createShape({ type: 'bpmn:Task' }), + target = elementFactory.createShape({ type: 'bpmn:Task' }), + messageFlow = elementFactory.createConnection({ type: 'bpmn:MessageFlow', source: source, target: target, waypoints: [] }); + + // then + expectCanCopy(messageFlow, [ source, target, messageFlow ], false); + })); + });