spiff-arena/bpmn-js-spiffworkflow/app/spiffworkflow/eventList.js

164 lines
4.5 KiB
JavaScript

import { is } from 'bpmn-js/lib/util/ModelUtil';
import { useService } from 'bpmn-js-properties-panel';
import {
ListGroup,
TextFieldEntry,
isTextFieldEntryEdited
} from '@bpmn-io/properties-panel';
import { getRoot } from './helpers';
/* This function creates a list of a particular event type at the process level using the item list
* and add function provided by `getArray`.
*
* Usage:
* const getArray = getArrayForType('bpmn:Signal', 'signalRef', 'Signal');
* const signalGroup = createGroupForType('signals', 'Signals', getArray);
*/
function getListGroupForType(groupId, label, getArray) {
return function (props) {
const { element, translate, moddle, commandStack } = props;
const eventArray = {
id: groupId,
element,
label: label,
component: ListGroup,
...getArray({ element, moddle, commandStack, translate }),
};
if (eventArray.items) {
return eventArray;
}
}
}
function getArrayForType(itemType, referenceType, prefix) {
return function (props) {
const { element, moddle, commandStack, translate } = props;
const root = getRoot(element.businessObject);
const matching = root.rootElements ? root.rootElements.filter(elem => elem.$type === itemType) : [];
function removeModelReferences(flowElements, match) {
flowElements.map(elem => {
if (elem.eventDefinitions)
elem.eventDefinitions = elem.eventDefinitions.filter(def => def.get(referenceType) != match);
else if (elem.flowElements)
removeModelReferences(elem.flowElements, match);
});
}
function removeElementReferences(children, match) {
children.map(child => {
if (child.businessObject.eventDefinitions) {
const bo = child.businessObject;
bo.eventDefinitions = bo.eventDefinitions.filter(def => def.get(referenceType) != match);
commandStack.execute('element.updateProperties', {
element: child,
moddleElement: bo,
properties: {}
});
}
if (child.children)
removeElementReferences(child.children, match);
});
}
function removeFactory(item) {
return function (event) {
event.stopPropagation();
if (root.rootElements) {
root.rootElements = root.rootElements.filter(elem => elem != item);
// This updates visible elements
removeElementReferences(element.children, item);
// This handles everything else (eg collapsed subprocesses) but does not update the shapes
// I can't figure out how to do that
root.rootElements.filter(elem => elem.$type === 'bpmn:Process').map(
process => removeModelReferences(process.flowElements, item)
);
commandStack.execute('element.updateProperties', {
element,
properties: {},
});
}
}
}
const items = matching.map((item, idx) => {
const itemId = `${prefix}-${idx}`;
return {
id: itemId,
label: item.name,
entries: getItemEditor({
itemId,
element,
item,
commandStack,
translate,
}),
autoFocusEntry: itemId,
remove: removeFactory(item),
};
});
function add(event) {
event.stopPropagation();
const item = moddle.create(itemType);
item.id = moddle.ids.nextPrefixed(`${prefix}_`);
item.name = item.id;
if (root.rootElements)
root.rootElements.push(item);
commandStack.execute('element.updateProperties', {
element,
properties: {},
});
};
return { items, add };
}
}
function getItemEditor(props) {
const { itemId, element, item, commandStack, translate } = props;
return [
{
id: `${itemId}-name`,
component: ItemTextField,
item,
commandStack,
translate,
},
];
}
function ItemTextField(props) {
const { itemId, element, item, commandStack, translate } = props;
const debounce = useService('debounceInput');
const setValue = (value) => {
commandStack.execute('element.updateModdleProperties', {
element,
moddleElement: item,
properties: {
id: value,
name: value,
},
});
};
const getValue = () => { return item.id; }
return TextFieldEntry({
element,
id: `${itemId}-id-textField`,
label: translate('ID'),
getValue,
setValue,
debounce,
});
}
export { getArrayForType, getListGroupForType };