Deleting any data object reference caused the associated data object to get deleted.

Fixes this so that only if you delete all references, wii the data object be removed.
Also assures that a new data object is not created when adding to a participant in a collaboration (an edge case bug(.
This commit is contained in:
Dan 2022-10-19 14:58:52 -04:00
parent b3eef6e52c
commit f28a3f89e4
3 changed files with 92 additions and 6 deletions

View File

@ -5,10 +5,20 @@
*/
export function findDataObjects(process) {
export function findDataObjects(parent) {
let dataObjects = [];
if (!process || !process.flowElements) {
return dataObjects;
let process;
if (!parent) {
return [];
}
if (parent.processRef) {
process = parent.processRef;
} else {
process = parent;
}
if (!process.flowElements) {
console.log("Process has no flow elements!", process)
return [];
}
for (const element of process.flowElements) {
if (element.$type === 'bpmn:DataObject') {

View File

@ -1,8 +1,10 @@
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
import { is } from 'bpmn-js/lib/util/ModelUtil';
import { findDataObjects } from './DataObjectHelpers';
import {getDi, is} from 'bpmn-js/lib/util/ModelUtil';
import {findDataObjects, findDataReferenceShapes} from './DataObjectHelpers';
var HIGH_PRIORITY = 1500;
import {
remove as collectionRemove,
} from 'diagram-js/lib/util/Collections';
/**
* This Command Interceptor functions like the BpmnUpdator in BPMN.js - It hooks into events
* from Diagram.js and updates the underlying BPMN model accordingly.
@ -53,6 +55,45 @@ export default class DataObjectInterceptor extends CommandInterceptor {
shape.businessObject.dataObjectRef = dataObject;
}
});
/**
* Don't remove the associated DataObject, unless all references to that data object
* Difficult to do given placement of this logic in the BPMN Updater, so we have
* to manually handle the removal.
*/
this.executed([ 'shape.delete' ], HIGH_PRIORITY, function(event) {
const { context } = event;
const { shape, oldParent } = context;
if (is(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') {
const references = findDataReferenceShapes(
oldParent,
shape.businessObject.dataObjectRef.id
);
if (references.length === 0) {
return; // Use the default bahavior and delete the data object.
}
// Remove the business Object
let containment = '';
const { businessObject } = shape;
if (is(businessObject, 'bpmn:DataOutputAssociation')) {
containment = 'dataOutputAssociations';
}
if (is(businessObject, 'bpmn:DataInputAssociation')) {
containment = 'dataInputAssociations';
}
const children = businessObject.$parent.get(containment);
collectionRemove(children, businessObject);
// Remove the visible element.
const di = getDi(shape);
const planeElements = di.$parent.get('planeElement');
collectionRemove(planeElements, di);
di.$parent = null;
// Stop the propogation.
event.stopPropagation();
}
});
}
}

View File

@ -50,6 +50,41 @@ describe('DataObject Interceptor', function() {
}));
it('Deleting a data object reference does not delete the data object, unless it is the last reference', inject(function(canvas, modeling) {
// IF - two dataObjectReferences are created
let rootShape = canvas.getRootElement();
const dataObjectRefShape1 = modeling.createShape({ type: 'bpmn:DataObjectReference' },
{ x: 220, y: 220 }, rootShape);
const dataObjectRefShape2 = modeling.createShape({ type: 'bpmn:DataObjectReference' },
{ x: 320, y: 220 }, rootShape);
// AND one is deleted
modeling.removeShape(dataObjectRefShape1)
// THEN - there is still a data object
const dataObjects = findDataObjects(rootShape.businessObject);
expect(dataObjects.length).to.equal(1);
}));
it('Deleting all the data references will also delete the data object', inject(function(canvas, modeling) {
// IF - two dataObjectReferences are created
let rootShape = canvas.getRootElement();
const dataObjectRefShape1 = modeling.createShape({ type: 'bpmn:DataObjectReference' },
{ x: 220, y: 220 }, rootShape);
const dataObjectRefShape2 = modeling.createShape({ type: 'bpmn:DataObjectReference' },
{ x: 320, y: 220 }, rootShape);
// AND both are deleted
modeling.removeShape(dataObjectRefShape1);
modeling.removeShape(dataObjectRefShape2);
// THEN - there is no data object
const dataObjects = findDataObjects(rootShape.businessObject);
expect(dataObjects.length).to.equal(0);
}));
it('Creating a new Reference will update the name to match the DataObject', inject(function(canvas, modeling) {
// IF - a Data Reference Exists