fixing a bug that was preventing the dropping of components in some situtations.
Adding new data object rules that will prevent you from moving a DataObject from one process to a sub-process. Fixing the Selection of Data Objects to properly use the command stack.
This commit is contained in:
parent
d20c7e8677
commit
ea56f270bc
|
@ -39,7 +39,10 @@ import spiffworkflow from 'bpmn-js-spiffworkflow/app/spiffworkflow';
|
|||
var bpmnJS = new BpmnModeler({
|
||||
additionalModules: [
|
||||
spiffworkflow
|
||||
]
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflowModdle: spiffModdleExtension
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
|
|
12
app/app.js
12
app/app.js
|
@ -1,13 +1,9 @@
|
|||
import BpmnModeler from 'bpmn-js/lib/Modeler';
|
||||
import diagramXML from '../resources/diagram.bpmn';
|
||||
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||
import inputOutput from './spiffworkflow/InputOutput';
|
||||
import SpiffWorkflowPropertiesProvider from './spiffworkflow/PropertiesPanel';
|
||||
import FileSaver from 'file-saver';
|
||||
import dataObjectInterceptor from './spiffworkflow/DataObject'; // For file downloads.
|
||||
import spiffworkflow from './spiffworkflow';
|
||||
|
||||
// Examples for extending the xml language can be found at
|
||||
// https://github.com/camunda/camunda-bpmn-moddle/blob/master/resources/camunda.json
|
||||
const modelerEl = document.getElementById('modeler');
|
||||
const panelEl = document.getElementById('panel');
|
||||
const spiffModdleExtension = require('./spiffworkflow/moddle/spiffworkflow.json');
|
||||
|
@ -19,14 +15,12 @@ const bpmnModeler = new BpmnModeler({
|
|||
parent: panelEl
|
||||
},
|
||||
additionalModules: [
|
||||
inputOutput,
|
||||
dataObjectInterceptor,
|
||||
SpiffWorkflowPropertiesProvider,
|
||||
spiffworkflow,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflow: spiffModdleExtension
|
||||
spiffworkflowModdle: spiffModdleExtension
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -6,20 +6,28 @@ var HIGH_PRIORITY = 1500;
|
|||
* 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 the case where a new DataObjectReference is added to the diagram. In such case
|
||||
* do NOT just create a new DataObject - rather, check to see if at least one DataObject already
|
||||
* exists, and if so, use that one.
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Prevent this from calling th CreateDataObjectBehavior in BPMN-js, as it will
|
||||
* 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
|
||||
* it is placed - as we want to reuse data objects if and when possible. */
|
||||
* 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) {
|
||||
event.stopPropagation();
|
||||
const context = event.context, shape = context.shape;
|
||||
if (is(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') {
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -28,10 +36,8 @@ export default class DataObjectInterceptor extends CommandInterceptor {
|
|||
this.executed([ 'shape.create' ], HIGH_PRIORITY, function(event) {
|
||||
const context = event.context, shape = context.shape;
|
||||
if (is(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') {
|
||||
console.log("Data Object Ref Exectuted");
|
||||
let process = shape.parent.businessObject;
|
||||
let existingDataObjects = findDataObjects(process);
|
||||
console.log("Existing Data Objects:", existingDataObjects);
|
||||
let dataObject;
|
||||
if (existingDataObjects.length > 0) {
|
||||
dataObject = existingDataObjects[0];
|
||||
|
@ -39,20 +45,13 @@ export default class DataObjectInterceptor extends CommandInterceptor {
|
|||
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 were removed.
|
||||
*/
|
||||
this.execute([ 'shape.delete' ], HIGH_PRIORITY, function(event) {
|
||||
let context = event.context;
|
||||
if ([ 'bpmn:DataObjectReference' ].includes(context.shape.type)) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Custom Rules for the DataObject - Rules allow you to prevent an
|
||||
* action from happening in the diagram, such as dropping an element
|
||||
* where it doesn't belong.
|
||||
*
|
||||
* Here we don't allow people to move a data object Reference
|
||||
* from one parent to another, as we can't move the data objects
|
||||
* from one parent to another.
|
||||
*
|
||||
*/
|
||||
import RuleProvider from 'diagram-js/lib/features/rules/RuleProvider';
|
||||
import inherits from 'inherits-browser';
|
||||
import { is } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import IoRules from '../InputOutput/IoRules';
|
||||
|
||||
export default function DataObjectRules(eventBus) {
|
||||
RuleProvider.call(this, eventBus);
|
||||
}
|
||||
inherits(DataObjectRules, RuleProvider);
|
||||
const HIGH_PRIORITY = 1500;
|
||||
|
||||
DataObjectRules.prototype.init = function() {
|
||||
this.addRule('elements.move', HIGH_PRIORITY,function(context) {
|
||||
let elements = context.shapes;
|
||||
let target = context.target;
|
||||
return canDrop(elements, target);
|
||||
});
|
||||
};
|
||||
|
||||
function canDrop(elements, target) {
|
||||
for (let element of elements) {
|
||||
if (is(element, 'bpmn:DataObjectReference') && element.parent && target) {
|
||||
return target === element.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IoRules.prototype.canDrop = canDrop;
|
|
@ -1,7 +1,14 @@
|
|||
import DataObjectInterceptor from './DataObjectInterceptor';
|
||||
import DataObjectRules from './DataObjectRules';
|
||||
import RulesModule from 'diagram-js/lib/features/rules';
|
||||
|
||||
|
||||
export default {
|
||||
__depends__: [
|
||||
RulesModule
|
||||
],
|
||||
__init__: [ 'DataInterceptor' ],
|
||||
DataInterceptor: [ 'type', DataObjectInterceptor ]
|
||||
DataInterceptor: [ 'type', DataObjectInterceptor ],
|
||||
DataObjectRules:[ 'type', DataObjectRules ]
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import IdGenerator from 'diagram-js/lib/util/IdGenerator';
|
|||
var HIGH_PRIORITY = 1500;
|
||||
|
||||
/**
|
||||
* This Command Intercetor functions like the BpmnUpdator in BPMN.js - It hooks into events
|
||||
* 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 the case where a new DataInput or DataOutput is added to
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import scriptGroup, { SCRIPT_TYPE } from './parts/ScriptGroup';
|
||||
import { is, isAny } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import dataReferenceGroup from './parts/DataReferenceGroup';
|
||||
import { DataObjectSelect } from './parts/DataObjectSelect';
|
||||
import { ListGroup, isTextFieldEntryEdited } from '@bpmn-io/properties-panel';
|
||||
import {DataObjectArray} from './parts/DataObjectArray';
|
||||
import { DataObjectArray } from './parts/DataObjectArray';
|
||||
const LOW_PRIORITY = 500;
|
||||
|
||||
export default function SpiffWorkflowPropertiesProvider(propertiesPanel, translate, moddle, commandStack, elementRegistry) {
|
||||
|
@ -15,7 +14,7 @@ export default function SpiffWorkflowPropertiesProvider(propertiesPanel, transla
|
|||
groups.push(preScriptPostScriptGroup(element, translate, moddle));
|
||||
}
|
||||
if (is(element, 'bpmn:DataObjectReference')) {
|
||||
groups.push(createDataObjectSelector(element, translate, moddle));
|
||||
groups.push(createDataObjectSelector(element, translate, moddle, commandStack));
|
||||
}
|
||||
if (is(element, 'bpmn:Process')) {
|
||||
groups.push(createDataObjectEditor(element, translate, moddle, commandStack, elementRegistry));
|
||||
|
@ -79,7 +78,7 @@ function preScriptPostScriptGroup(element, translate, moddle) {
|
|||
* @param moddle
|
||||
* @returns entries
|
||||
*/
|
||||
function createDataObjectSelector(element, translate, moddle) {
|
||||
function createDataObjectSelector(element, translate, moddle, commandStack) {
|
||||
return {
|
||||
id: 'data_object_properties',
|
||||
label: translate('Data Object Properties'),
|
||||
|
@ -89,7 +88,8 @@ function createDataObjectSelector(element, translate, moddle) {
|
|||
element,
|
||||
component: DataObjectSelect,
|
||||
isEdited: isTextFieldEntryEdited,
|
||||
moddle: moddle
|
||||
moddle: moddle,
|
||||
commandStack: commandStack,
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { useService } from 'bpmn-js-properties-panel';
|
||||
import { isTextFieldEntryEdited, TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
import { remove as collectionRemove } from 'diagram-js/lib/util/Collections';
|
||||
import { without } from 'min-dash';
|
||||
|
||||
/**
|
||||
|
@ -58,7 +57,6 @@ function removeFactory(props) {
|
|||
dataObject,
|
||||
process,
|
||||
commandStack,
|
||||
elementRegistry
|
||||
} = props;
|
||||
|
||||
|
||||
|
@ -85,18 +83,9 @@ function findDataObjects(process) {
|
|||
return dataObjects;
|
||||
}
|
||||
|
||||
export function findDataObject(process, id) {
|
||||
for (const dataObj of findDataObjects(process)) {
|
||||
if (dataObj.id == id) {
|
||||
return dataObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function DataObjectGroup(props) {
|
||||
const {
|
||||
idPrefix,
|
||||
element,
|
||||
dataObject
|
||||
} = props;
|
||||
|
||||
|
@ -122,7 +111,6 @@ function DataObjectTextField(props) {
|
|||
} = props;
|
||||
|
||||
const commandStack = useService('commandStack');
|
||||
const translate = useService('translate');
|
||||
const debounce = useService('debounceInput');
|
||||
|
||||
const setValue = (value) => {
|
||||
|
@ -138,8 +126,6 @@ function DataObjectTextField(props) {
|
|||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const getValue = (parameter) => {
|
||||
return dataObject.id;
|
||||
};
|
||||
|
|
|
@ -19,9 +19,8 @@ import { SelectEntry } from '@bpmn-io/properties-panel';
|
|||
* @returns {string|null|*}
|
||||
*/
|
||||
export function DataObjectSelect(props) {
|
||||
const moddle = props.moddle;
|
||||
const id = props.id;
|
||||
const element = props.element;
|
||||
const commandStack = props.commandStack;
|
||||
const debounce = useService('debounceInput');
|
||||
|
||||
|
||||
|
@ -31,9 +30,22 @@ export function DataObjectSelect(props) {
|
|||
|
||||
const setValue = value => {
|
||||
const businessObject = element.businessObject;
|
||||
for (const element of businessObject.$parent.flowElements) {
|
||||
if (element.$type === 'bpmn:DataObject' && element.id === value) {
|
||||
businessObject.dataObjectRef = element;
|
||||
for (const flowElem of businessObject.$parent.flowElements) {
|
||||
if (flowElem.$type === 'bpmn:DataObject' && flowElem.id === value) {
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: businessObject,
|
||||
properties: {
|
||||
dataObjectRef: flowElem
|
||||
}
|
||||
});
|
||||
commandStack.execute('element.updateProperties', {
|
||||
element,
|
||||
moddleElement: businessObject,
|
||||
properties: {
|
||||
'name': flowElem.id
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import IoPalette from './InputOutput/IoPalette';
|
||||
import IoRules from './InputOutput/IoRules';
|
||||
import IoInterceptor from './InputOutput/IoInterceptor';
|
||||
import SpiffWorkflowPropertiesProvider from './PropertiesPanel/SpiffWorkflowPropertiesProvider';
|
||||
import DataObjectInterceptor from './DataObject/DataObjectInterceptor';
|
||||
import DataObjectRules from './DataObject/DataObjectRules';
|
||||
import RulesModule from 'diagram-js/lib/features/rules';
|
||||
|
||||
export default {
|
||||
__depends__: [ RulesModule ],
|
||||
__init__: [
|
||||
'SpiffWorkflowPropertiesProvider',
|
||||
'DataObjectInterceptor', 'DataObjectRules',
|
||||
'IoPalette', 'IoRules', 'IoInterceptor' ],
|
||||
SpiffWorkflowPropertiesProvider: [ 'type', SpiffWorkflowPropertiesProvider ],
|
||||
DataObjectInterceptor: [ 'type', DataObjectInterceptor ],
|
||||
DataObjectRules:[ 'type', DataObjectRules ],
|
||||
IoPalette: [ 'type', IoPalette ],
|
||||
IoRules: [ 'type', IoRules ],
|
||||
IoInterceptor: [ 'type', IoInterceptor ],
|
||||
};
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
"bpmn-js-properties-panel": "^1.1.1",
|
||||
"diagram-js": "^8.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"inherits-browser": "^0.0.1",
|
||||
"min-dash": "^3.8.1",
|
||||
"min-dom": "^3.2.1",
|
||||
"moddle": "^5.0.3"
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
"bpmn-js-properties-panel": "^1.1.1",
|
||||
"diagram-js": "^8.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"inherits-browser": "^0.0.1",
|
||||
"min-dash": "^3.8.1",
|
||||
"min-dom": "^3.2.1",
|
||||
"moddle": "^5.0.3"
|
||||
|
|
|
@ -49,4 +49,21 @@ describe('DataObject Interceptor', function() {
|
|||
|
||||
}));
|
||||
|
||||
it('Creating a new Reference will update the name to match the DataObject', inject(function(canvas, modeling) {
|
||||
|
||||
// IF - a Data Reference Exists
|
||||
let rootShape = canvas.getRootElement();
|
||||
const dataObjectRefShape1 = modeling.createShape({ type: 'bpmn:DataObjectReference' },
|
||||
{ x: 220, y: 220 }, rootShape);
|
||||
|
||||
const dataObjects = findDataObjects(rootShape.businessObject);
|
||||
expect(dataObjectRefShape1.businessObject.name).to.equal(dataObjects[0].id);
|
||||
}));
|
||||
|
||||
it('will prevent dragging an existing data reference to a different process', inject(function(canvas, modeling) {
|
||||
|
||||
|
||||
}));
|
||||
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue