diff --git a/lib/features/popup-menu/ReplaceMenuProvider.js b/lib/features/popup-menu/ReplaceMenuProvider.js
index cba8c275..3c6ae5a8 100644
--- a/lib/features/popup-menu/ReplaceMenuProvider.js
+++ b/lib/features/popup-menu/ReplaceMenuProvider.js
@@ -77,6 +77,14 @@ ReplaceMenuProvider.prototype.getEntries = function(element) {
var differentType = isDifferentType(element);
+ if (is(businessObject, 'bpmn:DataObjectReference')) {
+ return this._createEntries(element, replaceOptions.DATA_OBJECT_REFERENCE);
+ }
+
+ if (is(businessObject, 'bpmn:DataStoreReference')) {
+ return this._createEntries(element, replaceOptions.DATA_STORE_REFERENCE);
+ }
+
// start events outside sub processes
if (is(businessObject, 'bpmn:StartEvent') && !is(businessObject.$parent, 'bpmn:SubProcess')) {
diff --git a/lib/features/replace/BpmnReplace.js b/lib/features/replace/BpmnReplace.js
index 5478963b..448c3a0b 100644
--- a/lib/features/replace/BpmnReplace.js
+++ b/lib/features/replace/BpmnReplace.js
@@ -84,6 +84,7 @@ export default function BpmnReplace(
moddleCopy,
modeling,
replace,
+ rules,
selection
) {
@@ -221,6 +222,11 @@ export default function BpmnReplace(
newElement.height = elementFactory._getDefaultSize(newBusinessObject).height;
}
+ if (!rules.allowed('shape.resize', { shape: newBusinessObject })) {
+ newElement.height = elementFactory._getDefaultSize(newBusinessObject).height;
+ newElement.width = elementFactory._getDefaultSize(newBusinessObject).width;
+ }
+
newBusinessObject.name = oldBusinessObject.name;
// retain default flow's reference between inclusive <-> exclusive gateways and activities
@@ -247,6 +253,15 @@ export default function BpmnReplace(
newElement.host = target.host;
}
+ // The DataStoreReference element is 14px wider than the DataObjectReference element
+ // This ensures that they stay centered on the x axis when replaced
+ if (
+ newElement.type === 'bpmn:DataStoreReference' ||
+ newElement.type === 'bpmn:DataObjectReference'
+ ) {
+ newElement.x = element.x + (element.width - newElement.width) / 2;
+ }
+
newElement.di = {};
// fill and stroke will be set to DI
@@ -273,6 +288,7 @@ BpmnReplace.$inject = [
'moddleCopy',
'modeling',
'replace',
+ 'rules',
'selection'
];
diff --git a/lib/features/replace/ReplaceOptions.js b/lib/features/replace/ReplaceOptions.js
index b132368e..d49e9b69 100644
--- a/lib/features/replace/ReplaceOptions.js
+++ b/lib/features/replace/ReplaceOptions.js
@@ -537,6 +537,28 @@ export var TASK = [
}
];
+export var DATA_OBJECT_REFERENCE = [
+ {
+ label: 'Data Store Reference',
+ actionName: 'replace-with-data-store-reference',
+ className: 'bpmn-icon-data-store',
+ target: {
+ type: 'bpmn:DataStoreReference'
+ }
+ }
+];
+
+export var DATA_STORE_REFERENCE = [
+ {
+ label: 'Data Object Reference',
+ actionName: 'replace-with-data-object-reference',
+ className: 'bpmn-icon-data-object',
+ target: {
+ type: 'bpmn:DataObjectReference'
+ }
+ }
+];
+
export var BOUNDARY_EVENT = [
{
label: 'Message Boundary Event',
diff --git a/lib/util/DiUtil.js b/lib/util/DiUtil.js
index 91c4e5a1..119cb54d 100644
--- a/lib/util/DiUtil.js
+++ b/lib/util/DiUtil.js
@@ -15,7 +15,7 @@ export function isExpanded(element) {
}
if (is(element, 'bpmn:SubProcess')) {
- return !!getBusinessObject(element).di.isExpanded;
+ return getBusinessObject(element).di && !!getBusinessObject(element).di.isExpanded;
}
if (is(element, 'bpmn:Participant')) {
diff --git a/test/fixtures/bpmn/features/replace/data-object.bpmn b/test/fixtures/bpmn/features/replace/data-elements.bpmn
similarity index 72%
rename from test/fixtures/bpmn/features/replace/data-object.bpmn
rename to test/fixtures/bpmn/features/replace/data-elements.bpmn
index 1476dd7b..d864deac 100644
--- a/test/fixtures/bpmn/features/replace/data-object.bpmn
+++ b/test/fixtures/bpmn/features/replace/data-elements.bpmn
@@ -4,20 +4,19 @@
+
+
-
-
-
-
+
-
-
-
-
+
+
+
+
diff --git a/test/spec/features/context-pad/ContextPadProviderSpec.js b/test/spec/features/context-pad/ContextPadProviderSpec.js
index bd6159fb..adfb5804 100644
--- a/test/spec/features/context-pad/ContextPadProviderSpec.js
+++ b/test/spec/features/context-pad/ContextPadProviderSpec.js
@@ -265,7 +265,7 @@ describe('features - context-pad', function() {
expectContextPadEntries('DataStoreReference', [
'connect',
'append.text-annotation',
- '!replace',
+ 'replace',
'!append.end-event'
]);
}));
@@ -489,11 +489,11 @@ describe('features - context-pad', function() {
// given
var rootShape = canvas.getRootElement(),
- dataStore = elementFactory.createShape({ type: 'bpmn:DataStoreReference' }),
+ group = elementFactory.createShape({ type: 'bpmn:Group' }),
replaceMenu;
// when
- create.start(canvasEvent({ x: 0, y: 0 }), dataStore);
+ create.start(canvasEvent({ x: 0, y: 0 }), group);
dragging.move(canvasEvent({ x: 50, y: 50 }));
dragging.hover({ element: rootShape });
diff --git a/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js b/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js
index 26cad9c0..983bfeaa 100644
--- a/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js
+++ b/test/spec/features/popup-menu/ReplaceMenuProviderSpec.js
@@ -29,7 +29,7 @@ describe('features/popup-menu - replace menu provider', function() {
var diagramXMLMarkers = require('../../../fixtures/bpmn/draw/activity-markers-simple.bpmn'),
diagramXMLReplace = require('../../../fixtures/bpmn/features/replace/01_replace.bpmn'),
- diagramXMLDataObject = require('../../../fixtures/bpmn/features/replace/data-object.bpmn');
+ diagramXMLDataElements = require('../../../fixtures/bpmn/features/replace/data-elements.bpmn');
var testModules = [
coreModule,
@@ -50,9 +50,10 @@ describe('features/popup-menu - replace menu provider', function() {
});
};
+
describe('data object - collection marker', function() {
- beforeEach(bootstrapModeler(diagramXMLDataObject, { modules: testModules }));
+ beforeEach(bootstrapModeler(diagramXMLDataElements, { modules: testModules }));
it('should toggle on', inject(function(elementRegistry) {
@@ -1202,6 +1203,50 @@ describe('features/popup-menu - replace menu provider', function() {
});
+ describe('data object', function() {
+
+ beforeEach(bootstrapModeler(diagramXMLDataElements, { modules: testModules }));
+
+
+ it('should only contain data store reference', inject(function(elementRegistry) {
+
+ // given
+ var dataObjectReference = elementRegistry.get('DataObjectReference_1');
+
+ // when
+ openPopup(dataObjectReference);
+
+ // then
+ expect(queryEntries()).to.have.length(2);
+ expect(queryEntry('toggle-is-collection')).to.exist;
+ expect(queryEntry('replace-with-data-store-reference')).to.exist;
+ expect(queryEntry('replace-with-data-object-reference')).to.be.null;
+ }));
+ });
+
+
+ describe('data store', function() {
+
+ beforeEach(bootstrapModeler(diagramXMLDataElements, { modules: testModules }));
+
+
+ it('should only contain data object reference', inject(function(elementRegistry) {
+
+ // given
+ var dataStoreReference = elementRegistry.get('DataStoreReference_1');
+
+ // when
+ openPopup(dataStoreReference);
+
+ // then
+ expect(queryEntries()).to.have.length(1);
+ expect(queryEntry('toggle-is-collection')).to.be.null;
+ expect(queryEntry('replace-with-data-store-reference')).to.be.null;
+ expect(queryEntry('replace-with-data-object-reference')).to.exist;
+ }));
+
+ });
+
});
diff --git a/test/spec/features/replace/BpmnReplaceSpec.js b/test/spec/features/replace/BpmnReplaceSpec.js
index f00ee2f3..b3bd02b4 100644
--- a/test/spec/features/replace/BpmnReplaceSpec.js
+++ b/test/spec/features/replace/BpmnReplaceSpec.js
@@ -1648,6 +1648,136 @@ describe('features/replace - bpmn replace', function() {
});
+
+ describe('center', function() {
+
+ var diagramXML = require('../../../fixtures/bpmn/features/replace/data-elements.bpmn');
+
+ var testModules = [
+ modelingModule,
+ coreModule
+ ];
+
+ beforeEach(bootstrapModeler(diagramXML, {
+ modules: testModules
+ }));
+
+
+ describe('data store reference to data object reference', function() {
+
+ it('should center on replace', inject(function(bpmnReplace, elementRegistry) {
+
+ // given
+ var dataStoreReference = elementRegistry.get('DataStoreReference_1');
+ var positionX = dataStoreReference.x;
+
+ // when
+ bpmnReplace.replaceElement(dataStoreReference, { type: 'bpmn:DataObjectReference' });
+
+ var dataObjectReference = elementRegistry.get('DataStoreReference_1');
+ var newPositionX = positionX + (dataStoreReference.width - dataObjectReference.width) / 2;
+
+ // then
+ expect(dataObjectReference.x).to.eql(newPositionX);
+ }));
+
+
+ it('should undo', inject(function(bpmnReplace, commandStack, elementRegistry) {
+
+ // given
+ var dataStoreReference = elementRegistry.get('DataStoreReference_1');
+ var positionX = dataStoreReference.x;
+
+ bpmnReplace.replaceElement(dataStoreReference, { type: 'bpmn:DataObjectReference' });
+
+ // when
+ commandStack.undo();
+
+ // then
+ expect(elementRegistry.get('DataStoreReference_1').x).to.eql(positionX);
+ }));
+
+
+ it('should redo', inject(function(bpmnReplace, commandStack, elementRegistry) {
+
+ // given
+ var dataStoreReference = elementRegistry.get('DataStoreReference_1');
+ var positionX = dataStoreReference.x;
+
+ bpmnReplace.replaceElement(dataStoreReference, { type: 'bpmn:DataObjectReference' });
+ commandStack.undo();
+
+ // when
+ commandStack.redo();
+
+ var dataObjectReference = elementRegistry.get('DataStoreReference_1');
+ var newPositionX = positionX + (dataStoreReference.width - dataObjectReference.width) / 2;
+
+ // then
+ expect(dataObjectReference.x).to.eql(newPositionX);
+ }));
+
+ });
+
+
+ describe('data object reference to data store reference', function() {
+
+ it('should center on replace', inject(function(bpmnReplace, elementRegistry) {
+
+ // given
+ var dataObjectReference = elementRegistry.get('DataObjectReference_1');
+ var positionX = dataObjectReference.x;
+
+ // when
+ bpmnReplace.replaceElement(dataObjectReference, { type: 'bpmn:DataStoreReference' });
+
+ var dataStoreReference = elementRegistry.get('DataObjectReference_1');
+ var newPositionX = positionX + (dataObjectReference.width - dataStoreReference.width) / 2;
+
+ // then
+ expect(dataStoreReference.x).to.eql(newPositionX);
+ }));
+
+
+ it('should undo', inject(function(bpmnReplace, commandStack, elementRegistry) {
+
+ // given
+ var dataObjectReference = elementRegistry.get('DataObjectReference_1');
+ var positionX = dataObjectReference.x;
+
+ bpmnReplace.replaceElement(dataObjectReference, { type: 'bpmn:DataStoreReference' });
+
+ // when
+ commandStack.undo();
+
+ // then
+ expect(elementRegistry.get('DataObjectReference_1').x).to.eql(positionX);
+ }));
+
+
+ it('should redo', inject(function(bpmnReplace, commandStack, elementRegistry) {
+
+ // given
+ var dataObjectReference = elementRegistry.get('DataObjectReference_1');
+ var positionX = dataObjectReference.x;
+
+ bpmnReplace.replaceElement(dataObjectReference, { type: 'bpmn:DataStoreReference' });
+ commandStack.undo();
+
+ // when
+ commandStack.redo();
+
+ var dataStoreReference = elementRegistry.get('DataObjectReference_1');
+ var newPositionX = positionX + (dataObjectReference.width - dataStoreReference.width) / 2;
+
+ // then
+ expect(dataStoreReference.x).to.eql(newPositionX);
+ }));
+
+ });
+
+ });
+
});