Merge pull request #27 from sartography/feature/multi-instance-task-panel
Feature/multi instance task panel
This commit is contained in:
commit
462a5e7778
29
app/app.js
29
app/app.js
|
@ -41,8 +41,33 @@ try {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The default importer drops the loop data inputs and outputs on multi instance tasks.
|
||||||
|
* They don't reference anything in our diagrams (which is a problem we should tackle, but not essential right now).
|
||||||
|
* This is probably a terrible solution, but given that the modifications happen every time a diagram is parsed,
|
||||||
|
* ia a locally defined function inside the parser, I don't see any other way of dealing with it than to just
|
||||||
|
* intercept the parsed results and patch them up again.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function importWithUnresolvedRefs(bpmnModeler, xml) {
|
||||||
|
bpmnModeler._moddle.fromXML(xml).then((result) => {
|
||||||
|
const refs = result.references.filter(r => r.property === 'bpmn:loopDataInputRef' || r.property === 'bpmn:loopDataOutputRef');
|
||||||
|
const desc = bpmnModeler._moddle.registry.getEffectiveDescriptor('bpmn:ItemAwareElement');
|
||||||
|
refs.forEach(ref => {
|
||||||
|
const props = {
|
||||||
|
id: ref.id,
|
||||||
|
name: ref.id ? typeof(ref.name) === 'undefined': ref.name,
|
||||||
|
};
|
||||||
|
let elem = bpmnModeler._moddle.create(desc, props);
|
||||||
|
elem.$parent = ref.element;
|
||||||
|
ref.element.set(ref.property, elem);
|
||||||
|
});
|
||||||
|
bpmnModeler.importDefinitions(result.rootElement);
|
||||||
|
bpmnModeler.open();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// import XML
|
// import XML
|
||||||
bpmnModeler.importXML(diagramXML).then(() => {});
|
importWithUnresolvedRefs(bpmnModeler, diagramXML);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is possible to populate certain components using API calls to
|
* It is possible to populate certain components using API calls to
|
||||||
|
@ -195,4 +220,4 @@ bpmnModeler.on('spiff.callactivity.search', (event) => {
|
||||||
// This handles the download and upload buttons - it isn't specific to
|
// This handles the download and upload buttons - it isn't specific to
|
||||||
// the BPMN modeler or these extensions, just a quick way to allow you to
|
// the BPMN modeler or these extensions, just a quick way to allow you to
|
||||||
// create and save files, so keeping it outside the example.
|
// create and save files, so keeping it outside the example.
|
||||||
setupFileOperations(bpmnModeler);
|
setupFileOperations(bpmnModeler, importWithUnresolvedRefs);
|
||||||
|
|
|
@ -7,11 +7,12 @@ import FileSaver from 'file-saver';
|
||||||
* easily from the editor for testing purposes.
|
* easily from the editor for testing purposes.
|
||||||
* -----------------------------------------
|
* -----------------------------------------
|
||||||
*/
|
*/
|
||||||
export default function setupFileOperations(bpmnModeler) {
|
export default function setupFileOperations(bpmnModeler, importWithUnresolvedRefs) {
|
||||||
/**
|
/**
|
||||||
* Just a quick bit of code so we can save the XML that is output.
|
* Just a quick bit of code so we can save the XML that is output.
|
||||||
* Helps for debugging against other libraries (like SpiffWorkflow)
|
* Helps for debugging against other libraries (like SpiffWorkflow)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const btn = document.getElementById('downloadButton');
|
const btn = document.getElementById('downloadButton');
|
||||||
btn.addEventListener('click', (_event) => {
|
btn.addEventListener('click', (_event) => {
|
||||||
saveXML();
|
saveXML();
|
||||||
|
@ -29,12 +30,8 @@ export default function setupFileOperations(bpmnModeler) {
|
||||||
*/
|
*/
|
||||||
const uploadBtn = document.getElementById('uploadButton');
|
const uploadBtn = document.getElementById('uploadButton');
|
||||||
uploadBtn.addEventListener('click', (_event) => {
|
uploadBtn.addEventListener('click', (_event) => {
|
||||||
openFile(displayFile);
|
openFile(bpmnModeler, importWithUnresolvedRefs);
|
||||||
});
|
});
|
||||||
|
|
||||||
function displayFile(contents) {
|
|
||||||
bpmnModeler.importXML(contents).then(() => {});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickElem(elem) {
|
function clickElem(elem) {
|
||||||
|
@ -59,7 +56,7 @@ function clickElem(elem) {
|
||||||
elem.dispatchEvent(eventMouse);
|
elem.dispatchEvent(eventMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function openFile(func) {
|
export function openFile(bpmnModeler, importWithUnresolvedRefs) {
|
||||||
const readFile = function readFileCallback(e) {
|
const readFile = function readFileCallback(e) {
|
||||||
const file = e.target.files[0];
|
const file = e.target.files[0];
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
@ -68,7 +65,7 @@ export function openFile(func) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = function onloadCallback(onloadEvent) {
|
reader.onload = function onloadCallback(onloadEvent) {
|
||||||
const contents = onloadEvent.target.result;
|
const contents = onloadEvent.target.result;
|
||||||
fileInput.func(contents);
|
importWithUnresolvedRefs(bpmnModeler, contents);
|
||||||
document.body.removeChild(fileInput);
|
document.body.removeChild(fileInput);
|
||||||
};
|
};
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
|
@ -77,7 +74,6 @@ export function openFile(func) {
|
||||||
fileInput.type = 'file';
|
fileInput.type = 'file';
|
||||||
fileInput.style.display = 'none';
|
fileInput.style.display = 'none';
|
||||||
fileInput.onchange = readFile;
|
fileInput.onchange = readFile;
|
||||||
fileInput.func = func;
|
|
||||||
document.body.appendChild(fileInput);
|
document.body.appendChild(fileInput);
|
||||||
clickElem(fileInput);
|
clickElem(fileInput);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import ConditionsPropertiesProvider from './conditions/propertiesPanel/Condition
|
||||||
import ExtensionsPropertiesProvider from './extensions/propertiesPanel/ExtensionsPropertiesProvider';
|
import ExtensionsPropertiesProvider from './extensions/propertiesPanel/ExtensionsPropertiesProvider';
|
||||||
import MessagesPropertiesProvider from './messages/propertiesPanel/MessagesPropertiesProvider';
|
import MessagesPropertiesProvider from './messages/propertiesPanel/MessagesPropertiesProvider';
|
||||||
import CallActivityPropertiesProvider from './callActivity/propertiesPanel/CallActivityPropertiesProvider';
|
import CallActivityPropertiesProvider from './callActivity/propertiesPanel/CallActivityPropertiesProvider';
|
||||||
|
import StandardLoopPropertiesProvider from './loops/propertiesPanel/StandardLoopPropertiesProvider';
|
||||||
|
import MultiInstancePropertiesProvider from './loops/propertiesPanel/MultiInstancePropertiesProvider';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
__depends__: [RulesModule],
|
__depends__: [RulesModule],
|
||||||
|
@ -25,6 +27,8 @@ export default {
|
||||||
'ioRules',
|
'ioRules',
|
||||||
'ioInterceptor',
|
'ioInterceptor',
|
||||||
'dataObjectRenderer',
|
'dataObjectRenderer',
|
||||||
|
'multiInstancePropertiesProvider',
|
||||||
|
'standardLoopPropertiesProvider',
|
||||||
],
|
],
|
||||||
dataObjectInterceptor: ['type', DataObjectInterceptor],
|
dataObjectInterceptor: ['type', DataObjectInterceptor],
|
||||||
dataObjectRules: ['type', DataObjectRules],
|
dataObjectRules: ['type', DataObjectRules],
|
||||||
|
@ -37,4 +41,6 @@ export default {
|
||||||
ioPalette: ['type', IoPalette],
|
ioPalette: ['type', IoPalette],
|
||||||
ioRules: ['type', IoRules],
|
ioRules: ['type', IoRules],
|
||||||
ioInterceptor: ['type', IoInterceptor],
|
ioInterceptor: ['type', IoInterceptor],
|
||||||
|
multiInstancePropertiesProvider: ['type', MultiInstancePropertiesProvider],
|
||||||
|
standardLoopPropertiesProvider: ['type', StandardLoopPropertiesProvider],
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
export function getLoopProperty(element, propertyName) {
|
||||||
|
|
||||||
|
const loopCharacteristics = element.businessObject.loopCharacteristics;
|
||||||
|
const prop = loopCharacteristics.get(propertyName);
|
||||||
|
|
||||||
|
let value = '';
|
||||||
|
if (typeof(prop) !== 'object') {
|
||||||
|
value = prop;
|
||||||
|
} else if (typeof(prop) !== 'undefined') {
|
||||||
|
if (prop.$type === 'bpmn:FormalExpression')
|
||||||
|
value = prop.get('body');
|
||||||
|
else
|
||||||
|
value = prop.get('id');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setLoopProperty(element, propertyName, value, commandStack) {
|
||||||
|
const loopCharacteristics = element.businessObject.loopCharacteristics;
|
||||||
|
if (typeof(value) === 'object')
|
||||||
|
value.$parent = loopCharacteristics;
|
||||||
|
commandStack.execute('element.updateModdleProperties', {
|
||||||
|
element,
|
||||||
|
moddleElement: loopCharacteristics,
|
||||||
|
properties: {
|
||||||
|
[propertyName]: value
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,227 @@
|
||||||
|
import { is } from 'bpmn-js/lib/util/ModelUtil';
|
||||||
|
import { useService } from 'bpmn-js-properties-panel';
|
||||||
|
import { TextFieldEntry, isTextFieldEntryEdited } from '@bpmn-io/properties-panel';
|
||||||
|
import { getLoopProperty, setLoopProperty } from './LoopProperty';
|
||||||
|
|
||||||
|
const LOW_PRIORITY = 500;
|
||||||
|
|
||||||
|
export default function MultiInstancePropertiesProvider(propertiesPanel) {
|
||||||
|
this.getGroups = function getGroupsCallback(element) {
|
||||||
|
return function pushGroup(groups) {
|
||||||
|
if (is(element, 'bpmn:Task') || is(element, 'bpmn:CallActivity')) {
|
||||||
|
let group = groups.filter(g => g.id == 'multiInstance');
|
||||||
|
if (group.length == 1)
|
||||||
|
updateMultiInstanceGroup(element, group[0]);
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
propertiesPanel.registerProvider(LOW_PRIORITY, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiInstancePropertiesProvider.$inject = ['propertiesPanel'];
|
||||||
|
|
||||||
|
function updateMultiInstanceGroup(element, group) {
|
||||||
|
group.entries = MultiInstanceProps({element});
|
||||||
|
group.shouldOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function MultiInstanceProps(props) {
|
||||||
|
const { element } = props;
|
||||||
|
|
||||||
|
const entries = [{
|
||||||
|
id: 'loopCardinality',
|
||||||
|
component: LoopCardinality,
|
||||||
|
isEdited: isTextFieldEntryEdited
|
||||||
|
}, {
|
||||||
|
id: 'loopDataInputRef',
|
||||||
|
component: InputCollection,
|
||||||
|
isEdited: isTextFieldEntryEdited
|
||||||
|
}, {
|
||||||
|
id: 'dataInputItem',
|
||||||
|
component: InputItem,
|
||||||
|
isEdited: isTextFieldEntryEdited
|
||||||
|
}, {
|
||||||
|
id: 'loopDataOutputRef',
|
||||||
|
component: OutputCollection,
|
||||||
|
isEdited: isTextFieldEntryEdited
|
||||||
|
}, {
|
||||||
|
id: 'dataOutputItem',
|
||||||
|
component: OutputItem,
|
||||||
|
isEdited: isTextFieldEntryEdited
|
||||||
|
}, {
|
||||||
|
id: 'completionCondition',
|
||||||
|
component: CompletionCondition,
|
||||||
|
isEdited: isTextFieldEntryEdited
|
||||||
|
}];
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
function LoopCardinality(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'loopCardinality');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
const loopCardinality = bpmnFactory.create('bpmn:FormalExpression', {body: value})
|
||||||
|
setLoopProperty(element, 'loopCardinality', loopCardinality, commandStack);
|
||||||
|
let inputCollection = getLoopProperty(element, 'loopDataInputRef');
|
||||||
|
if (typeof(value) !== 'undefined' && typeof(inputCollection) !== 'undefined')
|
||||||
|
setLoopProperty(element, 'loopDataInputRef', undefined, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: 'loopCardinality',
|
||||||
|
label: translate('Loop Cardinality'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce,
|
||||||
|
description: 'Explicitly set the number of instances'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function InputCollection(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'loopDataInputRef');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
const collection = bpmnFactory.create('bpmn:ItemAwareElement', {id: value});
|
||||||
|
setLoopProperty(element, 'loopDataInputRef', collection, commandStack);
|
||||||
|
let cardinality = getLoopProperty(element, 'loopCardinality');
|
||||||
|
if (typeof(value) !== 'undefined' && typeof(cardinality) !== 'undefined')
|
||||||
|
setLoopProperty(element, 'loopCardinality', undefined, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: 'loopDataInputRef',
|
||||||
|
label: translate('Input Collection'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce,
|
||||||
|
description: 'Create an instance for each item in this collection'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function InputItem(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'inputDataItem');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
const item = bpmnFactory.create('bpmn:DataInput', {id: value, name: value});
|
||||||
|
setLoopProperty(element, 'inputDataItem', item, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: 'inputDataItem',
|
||||||
|
label: translate('Input Element'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce,
|
||||||
|
description: 'Each item in the collection will be copied to this variable'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function OutputCollection(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'loopDataOutputRef');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
const collection = bpmnFactory.create('bpmn:ItemAwareElement', {id: value});
|
||||||
|
setLoopProperty(element, 'loopDataOutputRef', collection, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: 'loopDataOutputRef',
|
||||||
|
label: translate('Output Collection'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce,
|
||||||
|
description: 'Create or update this collection with the instance results'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function OutputItem(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'outputDataItem');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
const item = bpmnFactory.create('bpmn:DataOutput', {id: value, name: value});
|
||||||
|
setLoopProperty(element, 'outputDataItem', item, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: 'outputDataItem',
|
||||||
|
label: translate('Output Element'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce,
|
||||||
|
description: 'The value of this variable will be added to the output collection'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function CompletionCondition(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'completionCondition');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
const completionCondition = bpmnFactory.create('bpmn:FormalExpression', {body: value})
|
||||||
|
setLoopProperty(element, 'completionCondition', completionCondition, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: 'completionCondition',
|
||||||
|
label: translate('Completion Condition'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce,
|
||||||
|
description: 'Stop executing this task when this condition is met'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
import { is } from 'bpmn-js/lib/util/ModelUtil';
|
||||||
|
import { useService } from 'bpmn-js-properties-panel';
|
||||||
|
import {
|
||||||
|
Group,
|
||||||
|
TextFieldEntry,
|
||||||
|
isTextFieldEntryEdited,
|
||||||
|
CheckboxEntry,
|
||||||
|
isCheckboxEntryEdited,
|
||||||
|
} from '@bpmn-io/properties-panel';
|
||||||
|
|
||||||
|
import { getLoopProperty, setLoopProperty } from './LoopProperty';
|
||||||
|
|
||||||
|
const LOW_PRIORITY = 500;
|
||||||
|
|
||||||
|
export default function StandardLoopPropertiesProvider(propertiesPanel) {
|
||||||
|
this.getGroups = function getGroupsCallback(element) {
|
||||||
|
return function pushGroup(groups) {
|
||||||
|
if (
|
||||||
|
(is(element, 'bpmn:Task') || is(element, 'bpmn:CallActivity')) &&
|
||||||
|
typeof(element.businessObject.loopCharacteristics) !== 'undefined' &&
|
||||||
|
element.businessObject.loopCharacteristics.$type === 'bpmn:StandardLoopCharacteristics'
|
||||||
|
) {
|
||||||
|
const group = {
|
||||||
|
id: 'standardLoopCharacteristics',
|
||||||
|
component: Group,
|
||||||
|
label: 'Standard Loop',
|
||||||
|
entries: StandardLoopProps(element),
|
||||||
|
shouldOpen: true,
|
||||||
|
};
|
||||||
|
if (groups.length < 3)
|
||||||
|
groups.push(group);
|
||||||
|
else
|
||||||
|
groups.splice(2, 0, group);
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
propertiesPanel.registerProvider(LOW_PRIORITY, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardLoopPropertiesProvider.$inject = ['propertiesPanel'];
|
||||||
|
|
||||||
|
function StandardLoopProps(props) {
|
||||||
|
const { element } = props;
|
||||||
|
return [{
|
||||||
|
id: 'loopMaximum',
|
||||||
|
component: LoopMaximum,
|
||||||
|
isEdited: isTextFieldEntryEdited
|
||||||
|
}, {
|
||||||
|
id: 'loopCondition',
|
||||||
|
component: LoopCondition,
|
||||||
|
isEdited: isTextFieldEntryEdited
|
||||||
|
}, {
|
||||||
|
id: 'testBefore',
|
||||||
|
component: TestBefore,
|
||||||
|
isEdited: isCheckboxEntryEdited
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
function LoopMaximum(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'loopMaximum');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
setLoopProperty(element, 'loopMaximum', value, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: 'loopMaximum',
|
||||||
|
label: translate('Loop Maximum'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function TestBefore(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'testBefore');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
setLoopProperty(element, 'testBefore', value, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return CheckboxEntry({
|
||||||
|
element,
|
||||||
|
id: 'testBefore',
|
||||||
|
label: translate('Test Before'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function LoopCondition(props) {
|
||||||
|
const { element } = props;
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
const translate = useService('translate');
|
||||||
|
const commandStack = useService('commandStack');
|
||||||
|
const bpmnFactory = useService('bpmnFactory');
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return getLoopProperty(element, 'loopCondition');
|
||||||
|
};
|
||||||
|
|
||||||
|
const setValue = value => {
|
||||||
|
const loopCondition = bpmnFactory.create('bpmn:FormalExpression', {body: value})
|
||||||
|
setLoopProperty(element, 'loopCondition', loopCondition, commandStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: 'loopCondition',
|
||||||
|
label: translate('Loop Condition'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue