feat(copy-paste): clone properties when morphing to new element
Closes #648
This commit is contained in:
parent
432d7f4b7c
commit
2ecb9aeae4
|
@ -4,9 +4,15 @@ var ModelUtil = require('../../util/ModelUtil'),
|
|||
getBusinessObject = ModelUtil.getBusinessObject,
|
||||
is = ModelUtil.is;
|
||||
|
||||
var map = require('lodash/collection/map'),
|
||||
forEach = require('lodash/collection/forEach');
|
||||
var ModelCloneHelper = require('../../util/model/ModelCloneHelper');
|
||||
|
||||
var ModelCloneUtils = require('../../util/model/ModelCloneUtils'),
|
||||
getProperties = ModelCloneUtils.getProperties;
|
||||
|
||||
var IGNORED_PROPERTIES = ModelCloneUtils.IGNORED_PROPERTIES;
|
||||
|
||||
var filter = require('lodash/collection/filter'),
|
||||
forEach = require('lodash/collection/forEach');
|
||||
|
||||
function setProperties(descriptor, data, properties) {
|
||||
forEach(properties, function(property) {
|
||||
|
@ -26,61 +32,38 @@ function removeProperties(element, properties) {
|
|||
|
||||
function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, moddle, canvas, bpmnRules) {
|
||||
|
||||
var helper = new ModelCloneHelper();
|
||||
|
||||
copyPaste.registerDescriptor(function(element, descriptor) {
|
||||
var businessObject = getBusinessObject(element),
|
||||
conditionExpression,
|
||||
eventDefinitions;
|
||||
newBusinessObject = bpmnFactory.create(businessObject.$type);
|
||||
|
||||
var properties = getProperties(businessObject.$descriptor);
|
||||
|
||||
properties = filter(properties, function(property) {
|
||||
return IGNORED_PROPERTIES.indexOf(property.replace(/bpmn:/, '')) === -1;
|
||||
});
|
||||
|
||||
descriptor.businessObject = helper.clone(businessObject, newBusinessObject, properties);
|
||||
|
||||
descriptor.type = element.type;
|
||||
|
||||
setProperties(descriptor, businessObject.di, [ 'isExpanded' ]);
|
||||
|
||||
if (element.type === 'label') {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
setProperties(descriptor, businessObject, [
|
||||
'name',
|
||||
'text',
|
||||
'type',
|
||||
'processRef',
|
||||
'isInterrupting',
|
||||
'isForCompensation',
|
||||
'associationDirection',
|
||||
'triggeredByEvent',
|
||||
'cancelActivity'
|
||||
'triggeredByEvent'
|
||||
]);
|
||||
|
||||
if (businessObject.default) {
|
||||
descriptor.default = businessObject.default.id;
|
||||
}
|
||||
|
||||
if (businessObject.loopCharacteristics) {
|
||||
|
||||
descriptor.loopCharacteristics = {
|
||||
type: businessObject.loopCharacteristics.$type,
|
||||
isSequential: businessObject.loopCharacteristics.isSequential
|
||||
};
|
||||
}
|
||||
|
||||
setProperties(descriptor, businessObject.di, [ 'isExpanded' ]);
|
||||
|
||||
if (is(businessObject, 'bpmn:SequenceFlow')) {
|
||||
conditionExpression = businessObject.get('conditionExpression');
|
||||
|
||||
if (conditionExpression) {
|
||||
descriptor.conditionExpression = {
|
||||
type: conditionExpression.$type,
|
||||
body: conditionExpression.body
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
eventDefinitions = businessObject.get('eventDefinitions') || [];
|
||||
|
||||
if (eventDefinitions.length) {
|
||||
descriptor.eventDefinitions = map(eventDefinitions, function(defs) {
|
||||
return defs.$type;
|
||||
});
|
||||
}
|
||||
|
||||
return descriptor;
|
||||
});
|
||||
|
||||
|
@ -90,9 +73,6 @@ function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, moddle, canv
|
|||
parent = descriptor.parent,
|
||||
rootElement = canvas.getRootElement(),
|
||||
businessObject,
|
||||
newEventDefinition,
|
||||
conditionExpression,
|
||||
loopCharacteristics,
|
||||
source,
|
||||
target,
|
||||
canConnect;
|
||||
|
@ -132,59 +112,24 @@ function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, moddle, canv
|
|||
}
|
||||
}
|
||||
|
||||
descriptor.businessObject = businessObject = bpmnFactory.create(descriptor.type);
|
||||
businessObject = descriptor.businessObject;
|
||||
|
||||
// remove the id or else we cannot paste multiple times
|
||||
delete businessObject.id;
|
||||
|
||||
// assign an ID
|
||||
bpmnFactory._ensureId(businessObject);
|
||||
|
||||
if (descriptor.type === 'bpmn:Participant' && descriptor.processRef) {
|
||||
descriptor.processRef = businessObject.processRef = bpmnFactory.create('bpmn:Process');
|
||||
}
|
||||
|
||||
setProperties(businessObject, descriptor, [
|
||||
'name',
|
||||
'text',
|
||||
'isExpanded',
|
||||
'isInterrupting',
|
||||
'cancelActivity',
|
||||
'triggeredByEvent'
|
||||
]);
|
||||
|
||||
if (descriptor.loopCharacteristics) {
|
||||
loopCharacteristics = descriptor.loopCharacteristics;
|
||||
|
||||
businessObject.loopCharacteristics = moddle.create(loopCharacteristics.type);
|
||||
|
||||
if (loopCharacteristics.isSequential) {
|
||||
businessObject.loopCharacteristics.isSequential = true;
|
||||
}
|
||||
|
||||
businessObject.loopCharacteristics.$parent = businessObject;
|
||||
}
|
||||
|
||||
if (descriptor.conditionExpression) {
|
||||
conditionExpression = descriptor.conditionExpression;
|
||||
|
||||
businessObject.conditionExpression = moddle.create(conditionExpression.type, { body: conditionExpression.body });
|
||||
|
||||
businessObject.conditionExpression.$parent = businessObject;
|
||||
}
|
||||
|
||||
if (descriptor.eventDefinitions) {
|
||||
businessObject.eventDefinitions = map(descriptor.eventDefinitions, function(type) {
|
||||
newEventDefinition = moddle.create(type);
|
||||
|
||||
newEventDefinition.$parent = businessObject;
|
||||
|
||||
return newEventDefinition;
|
||||
});
|
||||
}
|
||||
|
||||
removeProperties(descriptor, [
|
||||
'name',
|
||||
'text',
|
||||
'eventDefinitions',
|
||||
'conditionExpression',
|
||||
'loopCharacteristics',
|
||||
'isInterrupting',
|
||||
'cancelActivity',
|
||||
'triggeredByEvent'
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -13,4 +13,5 @@ TestHelper.insertCSS('diagram-js-testing.css',
|
|||
|
||||
// add suite specific matchers
|
||||
global.chai.use(require('diagram-js/test/matchers/BoundsMatchers'));
|
||||
global.chai.use(require('diagram-js/test/matchers/ConnectionMatchers'));
|
||||
global.chai.use(require('diagram-js/test/matchers/ConnectionMatchers'));
|
||||
global.chai.use(require('./matchers/JSONMatcher'));
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = function(chai, utils) {
|
||||
|
||||
utils.addMethod(chai.Assertion.prototype, 'jsonEqual', function(comparison) {
|
||||
|
||||
var actual = JSON.stringify(this._obj);
|
||||
var expected = JSON.stringify(comparison);
|
||||
|
||||
this.assert(
|
||||
actual == expected,
|
||||
'expected #{this} to deep equal #{act}',
|
||||
'expected #{this} not to deep equal #{act}',
|
||||
comparison, // expected
|
||||
this._obj, // actual
|
||||
true // show diff
|
||||
);
|
||||
});
|
||||
};
|
|
@ -11,17 +11,20 @@ var bpmnCopyPasteModule = require('../../../../lib/features/copy-paste'),
|
|||
coreModule = require('../../../../lib/core');
|
||||
|
||||
var map = require('lodash/collection/map'),
|
||||
filter = require('lodash/collection/filter'),
|
||||
forEach = require('lodash/collection/forEach'),
|
||||
uniq = require('lodash/array/uniq');
|
||||
|
||||
var DescriptorTree = require('./DescriptorTree');
|
||||
|
||||
var is = require('../../../../lib/util/ModelUtil').is;
|
||||
|
||||
describe('features/copy-paste', function() {
|
||||
|
||||
var testModules = [ bpmnCopyPasteModule, copyPasteModule, tooltipsModule, modelingModule, coreModule ];
|
||||
|
||||
var basicXML = require('../../../fixtures/bpmn/features/copy-paste/basic.bpmn'),
|
||||
clonePropertiesXML = require('../../../fixtures/bpmn/features/replace/clone-properties.bpmn'),
|
||||
propertiesXML = require('../../../fixtures/bpmn/features/copy-paste/properties.bpmn'),
|
||||
collaborationXML = require('../../../fixtures/bpmn/features/copy-paste/collaboration.bpmn'),
|
||||
collaborationMultipleXML = require('../../../fixtures/bpmn/features/copy-paste/collaboration-multiple.bpmn'),
|
||||
|
@ -37,19 +40,10 @@ describe('features/copy-paste', function() {
|
|||
|
||||
it('selected elements', inject(function(elementRegistry, copyPaste) {
|
||||
|
||||
// given
|
||||
var subProcess,
|
||||
startEvent,
|
||||
boundaryEvent,
|
||||
textAnnotation;
|
||||
|
||||
// when
|
||||
var tree = copy([ 'SubProcess_1kd6ist' ]);
|
||||
|
||||
startEvent = tree.getElement('StartEvent_1');
|
||||
boundaryEvent = tree.getElement('BoundaryEvent_1c94bi9');
|
||||
subProcess = tree.getElement('SubProcess_1kd6ist');
|
||||
textAnnotation = tree.getElement('TextAnnotation_0h1hhgg');
|
||||
var subProcess = tree.getElement('SubProcess_1kd6ist');
|
||||
|
||||
// then
|
||||
expect(tree.getLength()).to.equal(3);
|
||||
|
@ -59,9 +53,6 @@ describe('features/copy-paste', function() {
|
|||
expect(tree.getDepthLength(2)).to.equal(15);
|
||||
|
||||
expect(subProcess.isExpanded).to.be.true;
|
||||
expect(startEvent.name).to.equal('hello');
|
||||
expect(textAnnotation.text).to.equal('foo');
|
||||
expect(boundaryEvent.eventDefinitions).to.contain('bpmn:TimerEventDefinition');
|
||||
}));
|
||||
|
||||
});
|
||||
|
@ -512,6 +503,57 @@ describe('features/copy-paste', function() {
|
|||
|
||||
});
|
||||
|
||||
|
||||
describe('deep properties', function() {
|
||||
|
||||
var camundaPackage = require('../../../fixtures/json/model/camunda');
|
||||
|
||||
beforeEach(bootstrapModeler(clonePropertiesXML, {
|
||||
modules: testModules,
|
||||
moddleExtensions: {
|
||||
camunda: camundaPackage
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
it('integration', inject(integrationTest([ 'Participant_0x9lnke' ])));
|
||||
|
||||
|
||||
it('should copy UserTask properties',
|
||||
inject(function(elementRegistry, copyPaste, canvas) {
|
||||
|
||||
var participant = elementRegistry.get('Participant_0x9lnke'),
|
||||
task = elementRegistry.get('Task_1'),
|
||||
newTask;
|
||||
|
||||
// when
|
||||
copyPaste.copy([ task ]);
|
||||
|
||||
copyPaste.paste({
|
||||
element: participant,
|
||||
point: {
|
||||
x: 500,
|
||||
y: 50
|
||||
}
|
||||
});
|
||||
|
||||
newTask = filter(participant.children, function(element) {
|
||||
return is(element, 'bpmn:Task');
|
||||
})[0];
|
||||
|
||||
// then
|
||||
var bo = task.businessObject;
|
||||
var copiedBo = newTask.businessObject;
|
||||
|
||||
|
||||
expect(copiedBo.asyncBefore).to.eql(bo.asyncBefore);
|
||||
expect(copiedBo.documentation).to.jsonEqual(bo.documentation);
|
||||
expect(copiedBo.extensionElements).to.jsonEqual(bo.extensionElements);
|
||||
})
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue