spiff-arena/app/spiffworkflow/DataObject/DataObjectInterceptor.js
jasquat bb86175687 Squashed 'bpmn-js-spiffworkflow/' changes from b3eef6e52..9c0da0240
9c0da0240 Merge pull request #21 from sartography/bug/data_objects
6fe36aeb0 Minor fixes.
d21cb75fb Assure we aren't setting the properties on every service task to the same thing.
f28a3f89e 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(.

git-subtree-dir: bpmn-js-spiffworkflow
git-subtree-split: 9c0da02406ecbc51cfd7fd1ed1f2f311101d9987
2022-10-19 16:16:54 -04:00

101 lines
4.1 KiB
JavaScript

import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
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.
*
* This handles some special cases we want to handle for DataObjects and DataObjectReferences,
* for instance:
* 1) Use existing data objects if possible when creating a new reference (don't create new objects each time)
* 2) Don't automatically delete a data object when you delete the reference - unless all references are removed.
* 3) Update the name of the DataObjectReference to match the id of the DataObject.
* 4) Don't allow someone to move a DataObjectReference from one process to another process.
*/
export default class DataObjectInterceptor extends CommandInterceptor {
constructor(eventBus, bpmnFactory, bpmnUpdater) {
super(eventBus);
/**
* For DataObjectReferences only ...
* Prevent this from calling the CreateDataObjectBehavior in BPMN-js, as it will
* attempt to crete a dataObject immediately. We can't create the dataObject until
* we know where it is placed - as we want to reuse data objects of the parent when
* possible */
this.preExecute([ 'shape.create' ], HIGH_PRIORITY, function(event) {
const context = event.context, shape = context.shape;
if (is(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') {
event.stopPropagation();
}
});
/**
* Don't just create a new data object, use the first existing one if it already exists
*/
this.executed([ 'shape.create' ], HIGH_PRIORITY, function(event) {
const context = event.context, shape = context.shape;
if (is(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') {
let process = shape.parent.businessObject;
let existingDataObjects = findDataObjects(process);
let dataObject;
if (existingDataObjects.length > 0) {
dataObject = existingDataObjects[0];
} else {
dataObject = bpmnFactory.create('bpmn:DataObject');
}
// Update the name of the reference to match the data object's id.
shape.businessObject.name = dataObject.id;
// set the reference to the DataObject
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();
}
});
}
}
DataObjectInterceptor.$inject = [ 'eventBus', 'bpmnFactory', 'bpmnUpdater' ];