Enhance UX to fix multi instance bug (#75)
* Enhance UX to fix multi instance bug * Multinstance changes commit * Add removeloopProperty
This commit is contained in:
parent
91aa2f5933
commit
c39627b959
|
@ -16,8 +16,8 @@ import SignalPropertiesProvider from './signals/propertiesPanel/SignalProperties
|
|||
import ErrorPropertiesProvider from './errors/propertiesPanel/ErrorPropertiesProvider';
|
||||
import EscalationPropertiesProvider from './escalations/propertiesPanel/EscalationPropertiesProvider';
|
||||
import CallActivityPropertiesProvider from './callActivity/propertiesPanel/CallActivityPropertiesProvider';
|
||||
import StandardLoopPropertiesProvider from './loops/propertiesPanel/StandardLoopPropertiesProvider';
|
||||
import MultiInstancePropertiesProvider from './loops/propertiesPanel/MultiInstancePropertiesProvider';
|
||||
import StandardLoopPropertiesProvider from './loops/StandardLoopPropertiesProvider';
|
||||
import MultiInstancePropertiesProvider from './loops/MultiInstancePropertiesProvider';
|
||||
import CallActivityInterceptor from './callActivity/CallActivityInterceptor';
|
||||
import MessageInterceptor from './messages/MessageInterceptor';
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable no-param-reassign */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { is } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import { isTextFieldEntryEdited, isCheckboxEntryEdited } from '@bpmn-io/properties-panel';
|
||||
import { InputItem } from './propertiesPanel/InputItemEntry';
|
||||
import { LoopCardinality } from './propertiesPanel/LoopCardinalityEntry';
|
||||
import { InputCollection } from './propertiesPanel/InputCollectionEntry';
|
||||
import { OutputItem } from './propertiesPanel/OutputItemEntry';
|
||||
import { OutputCollection } from './propertiesPanel/OutputCollectionEntry';
|
||||
import { CompletionCondition } from './propertiesPanel/CompletionConditionEntry';
|
||||
import { IsOutputElSync } from './propertiesPanel/IsIOSyncEntry';
|
||||
|
||||
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') ||
|
||||
is(element, 'bpmn:SubProcess')
|
||||
) {
|
||||
const 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 { businessObject } = element;
|
||||
|
||||
return [
|
||||
{
|
||||
id: 'loopCardinality',
|
||||
component: LoopCardinality,
|
||||
isEdited: isTextFieldEntryEdited,
|
||||
},
|
||||
{
|
||||
id: 'loopDataInputRef',
|
||||
component: InputCollection,
|
||||
isEdited: isTextFieldEntryEdited,
|
||||
},
|
||||
{
|
||||
id: 'dataInputItem',
|
||||
component: InputItem,
|
||||
isEdited: isTextFieldEntryEdited,
|
||||
},
|
||||
{
|
||||
id: 'isOutputElSynchronized',
|
||||
component: IsOutputElSync,
|
||||
isEdited: isCheckboxEntryEdited,
|
||||
},
|
||||
{
|
||||
id: 'loopDataOutputRef',
|
||||
component: OutputCollection,
|
||||
isEdited: isTextFieldEntryEdited,
|
||||
},
|
||||
!businessObject.get('spiffworkflow:isOutputSynced')
|
||||
? {
|
||||
id: 'dataOutputItem',
|
||||
component: OutputItem,
|
||||
isEdited: isTextFieldEntryEdited,
|
||||
}
|
||||
: {},
|
||||
{
|
||||
id: 'completionCondition',
|
||||
component: CompletionCondition,
|
||||
isEdited: isTextFieldEntryEdited,
|
||||
},
|
||||
];
|
||||
}
|
|
@ -1,133 +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') || is(element, 'bpmn:SubProcess')) &&
|
||||
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
|
||||
});
|
||||
}
|
||||
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 './helpers';
|
||||
|
||||
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') || is(element, 'bpmn:SubProcess')) &&
|
||||
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
|
||||
});
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
export function getLoopProperty(element, propertyName) {
|
||||
const { loopCharacteristics } = element.businessObject;
|
||||
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;
|
||||
|
||||
if (typeof (value) === 'object') {
|
||||
value.$parent = loopCharacteristics;
|
||||
}
|
||||
|
||||
const properties = { [propertyName]: value };
|
||||
if (propertyName === 'loopCardinality') properties.loopDataInputRef = undefined;
|
||||
if (propertyName === 'loopDataInputRef') properties.loopCardinality = undefined;
|
||||
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: loopCharacteristics,
|
||||
properties,
|
||||
});
|
||||
}
|
||||
|
||||
export function removeLoopProperty(element, propertyName, commandStack) {
|
||||
const { loopCharacteristics } = element.businessObject;
|
||||
const properties = { [propertyName]: undefined };
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: loopCharacteristics,
|
||||
properties,
|
||||
});
|
||||
}
|
||||
|
||||
export function setIsIOValue(element, value, commandStack) {
|
||||
commandStack.execute('element.updateProperties', {
|
||||
element,
|
||||
properties: {
|
||||
'spiffworkflow:isOutputSynced': value,
|
||||
},
|
||||
});
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable import/order */
|
||||
|
||||
import { useService } from "bpmn-js-properties-panel";
|
||||
import { getLoopProperty, removeLoopProperty, setLoopProperty } from "../helpers";
|
||||
import { TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
|
||||
export 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) => {
|
||||
if (!value || value === '') {
|
||||
// If value is empty, remove completionCondition from XML
|
||||
removeLoopProperty(element, 'completionCondition', commandStack);
|
||||
return;
|
||||
}
|
||||
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,41 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable import/order */
|
||||
|
||||
import { useService } from "bpmn-js-properties-panel";
|
||||
import { getLoopProperty, removeLoopProperty, setLoopProperty } from "../helpers";
|
||||
import { TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
|
||||
export 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) => {
|
||||
if (!value || value === '') {
|
||||
// If value is empty or undefined, remove loopDataInputRef from XML
|
||||
removeLoopProperty(element, 'loopDataInputRef', commandStack);
|
||||
return;
|
||||
}
|
||||
const collection = bpmnFactory.create('bpmn:ItemAwareElement', {
|
||||
id: value,
|
||||
});
|
||||
setLoopProperty(element, 'loopDataInputRef', collection, commandStack);
|
||||
};
|
||||
|
||||
return TextFieldEntry({
|
||||
element,
|
||||
id: 'loopDataInputRef',
|
||||
label: translate('Input Collection'),
|
||||
getValue,
|
||||
setValue,
|
||||
debounce,
|
||||
description: 'Create an instance for each item in this collection',
|
||||
});
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable import/order */
|
||||
|
||||
import { useService } from "bpmn-js-properties-panel";
|
||||
import { getLoopProperty, setLoopProperty } from "../helpers";
|
||||
import { TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
|
||||
export 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 =
|
||||
typeof value !== 'undefined' && value !== ''
|
||||
? bpmnFactory.create('bpmn:DataInput', { id: value, name: value })
|
||||
: undefined;
|
||||
setLoopProperty(element, 'inputDataItem', item, commandStack);
|
||||
|
||||
try {
|
||||
const { businessObject } = element;
|
||||
if (businessObject.get('spiffworkflow:isOutputSynced')) {
|
||||
setLoopProperty(element, 'outputDataItem', item, commandStack);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Error caught while set value Input item', error);
|
||||
}
|
||||
};
|
||||
|
||||
return TextFieldEntry({
|
||||
element,
|
||||
id: 'inputDataItem',
|
||||
label: translate('Input Element'),
|
||||
getValue,
|
||||
setValue,
|
||||
debounce,
|
||||
description: 'Each item in the collection will be copied to this variable',
|
||||
});
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable import/order */
|
||||
|
||||
import { useService } from "bpmn-js-properties-panel";
|
||||
import { getLoopProperty, removeLoopProperty, setIsIOValue, setLoopProperty } from "../helpers";
|
||||
import { CheckboxEntry } from '@bpmn-io/properties-panel';
|
||||
|
||||
export function IsOutputElSync(props) {
|
||||
const { element } = props;
|
||||
const translate = useService('translate');
|
||||
const commandStack = useService('commandStack');
|
||||
const bpmnFactory = useService('bpmnFactory');
|
||||
|
||||
const getValue = () => {
|
||||
const { businessObject } = element;
|
||||
return businessObject.get('spiffworkflow:isOutputSynced')
|
||||
? businessObject.get('spiffworkflow:isOutputSynced')
|
||||
: false;
|
||||
};
|
||||
|
||||
const setValue = (value) => {
|
||||
if (value) {
|
||||
const valIn = getLoopProperty(element, 'inputDataItem');
|
||||
const item =
|
||||
typeof valIn !== 'undefined' && valIn !== ''
|
||||
? bpmnFactory.create('bpmn:DataOutput', { id: valIn, name: valIn })
|
||||
: undefined;
|
||||
if(item){
|
||||
// If DataInput Item is found and set, add new DataOut with same value
|
||||
setLoopProperty(element, 'outputDataItem', item, commandStack);
|
||||
}
|
||||
} else {
|
||||
// Remove DataOutput value when isIoSync is disabled
|
||||
removeLoopProperty(element, 'outputDataItem', commandStack);
|
||||
}
|
||||
|
||||
setIsIOValue(element, value, commandStack);
|
||||
};
|
||||
|
||||
return CheckboxEntry({
|
||||
element,
|
||||
id: 'testBefore',
|
||||
label: translate('Output Element is Synchronized with Input Element'),
|
||||
getValue,
|
||||
setValue,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable import/order */
|
||||
|
||||
import { useService } from "bpmn-js-properties-panel";
|
||||
import { getLoopProperty, removeLoopProperty, setLoopProperty } from "../helpers";
|
||||
import { TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
|
||||
export 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) => {
|
||||
if (!value || value === '') {
|
||||
// If value is empty or undefined, remove loopCardinality from XML
|
||||
removeLoopProperty(element, 'loopCardinality', commandStack);
|
||||
return;
|
||||
}
|
||||
const loopCardinality = bpmnFactory.create('bpmn:FormalExpression', {
|
||||
body: value,
|
||||
});
|
||||
setLoopProperty(element, 'loopCardinality', loopCardinality, commandStack);
|
||||
};
|
||||
|
||||
return TextFieldEntry({
|
||||
element,
|
||||
id: 'loopCardinality',
|
||||
label: translate('Loop Cardinality'),
|
||||
getValue,
|
||||
setValue,
|
||||
debounce,
|
||||
description: 'Explicitly set the number of instances',
|
||||
});
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
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;
|
||||
let properties = { [propertyName]: value };
|
||||
if (propertyName === 'loopCardinality') properties['loopDataInputRef'] = undefined;
|
||||
if (propertyName === 'loopDataInputRef') properties['loopCardinality'] = undefined;
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: loopCharacteristics,
|
||||
properties: properties,
|
||||
});
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
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') || is(element, 'bpmn:SubProcess')) {
|
||||
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);
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
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 = (typeof(value) !== 'undefined') ? bpmnFactory.create('bpmn:DataInput', {id: value, name: value}) : undefined;
|
||||
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 = (typeof(value) !== 'undefined') ? bpmnFactory.create('bpmn:DataOutput', {id: value, name: value}) : undefined;
|
||||
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,41 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable import/order */
|
||||
|
||||
import { useService } from "bpmn-js-properties-panel";
|
||||
import { getLoopProperty, removeLoopProperty, setLoopProperty } from "../helpers";
|
||||
import { TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
|
||||
export 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) => {
|
||||
if (!value || value === '') {
|
||||
// If value is empty or undefined, remove loopDataOutputRef from XML
|
||||
removeLoopProperty(element, 'loopDataOutputRef', commandStack);
|
||||
return;
|
||||
}
|
||||
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',
|
||||
});
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
/* eslint-disable import/order */
|
||||
import { useService } from "bpmn-js-properties-panel";
|
||||
import { getLoopProperty, setLoopProperty } from "../helpers";
|
||||
import { TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
|
||||
|
||||
export 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) => {
|
||||
try {
|
||||
const inVal = getLoopProperty(element, 'inputDataItem');
|
||||
if (inVal === value) {
|
||||
alert( 'You have entered the same value for both Input and Output elements without enabling synchronization. Please confirm if this is intended.' );
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Error caught while Set Value OutputItem', error);
|
||||
}
|
||||
|
||||
const item =
|
||||
typeof value !== 'undefined' && value !== ''
|
||||
? bpmnFactory.create('bpmn:DataOutput', { id: value, name: value })
|
||||
: undefined;
|
||||
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',
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue