In and Out Variables for Tasks (#84)
* INIT * Input Group * Output group and CSS Alignments * Add unit tests * fix typing issue
This commit is contained in:
parent
c39627b959
commit
020de78f82
|
@ -74,9 +74,22 @@ adjust CSS props so that padding won't add to dimensions.
|
||||||
|
|
||||||
.bio-properties-panel-group-entries > .bio-properties-panel-description {
|
.bio-properties-panel-group-entries > .bio-properties-panel-description {
|
||||||
padding-inline: 15px;
|
padding-inline: 15px;
|
||||||
padding-block: 8px;
|
padding-block: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bio-properties-panel-group-entries.open > .bio-properties-panel-group {
|
||||||
|
margin-inline: 15px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 8px;
|
||||||
|
/* box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
transition: border-color 0.3s, box-shadow 0.3s; */
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .bio-properties-panel-group + .bio-properties-panel-group {
|
||||||
|
margin-top: 10px;
|
||||||
|
} */
|
||||||
|
|
||||||
/* Darker background on mouse-over */
|
/* Darker background on mouse-over */
|
||||||
.bpmn-js-spiffworkflow-btn:hover {
|
.bpmn-js-spiffworkflow-btn:hover {
|
||||||
background-color: RoyalBlue;
|
background-color: RoyalBlue;
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
|
||||||
|
export function createSpecification(bpmnFactory, businessObject, type, newElement) {
|
||||||
|
let ioSpecification = businessObject.ioSpecification;
|
||||||
|
if (!ioSpecification) {
|
||||||
|
ioSpecification = bpmnFactory.create('bpmn:InputOutputSpecification', {
|
||||||
|
dataInputs: [],
|
||||||
|
dataOutputs: [],
|
||||||
|
inputSets: [],
|
||||||
|
outputSets: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
businessObject.ioSpecification = ioSpecification;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'input') {
|
||||||
|
ioSpecification.dataInputs.push(newElement);
|
||||||
|
if (!ioSpecification.inputSets.length) {
|
||||||
|
ioSpecification.inputSets.push(bpmnFactory.create('bpmn:InputSet', { dataInputRefs: [newElement] }));
|
||||||
|
} else {
|
||||||
|
ioSpecification.inputSets[0].dataInputRefs.push(newElement);
|
||||||
|
}
|
||||||
|
} else if (type === 'output') {
|
||||||
|
ioSpecification.dataOutputs.push(newElement);
|
||||||
|
if (!ioSpecification.outputSets.length) {
|
||||||
|
ioSpecification.outputSets.push(bpmnFactory.create('bpmn:OutputSet', { dataOutputRefs: [newElement] }));
|
||||||
|
} else {
|
||||||
|
ioSpecification.outputSets[0].dataOutputRefs.push(newElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioSpecification;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeElementFromSpecification(element, entry, type) {
|
||||||
|
const ioSpecification = element.businessObject.ioSpecification;
|
||||||
|
if (!ioSpecification) {
|
||||||
|
console.error('No ioSpecification found for this element.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const collection = type === 'input' ? ioSpecification.dataInputs : ioSpecification.dataOutputs;
|
||||||
|
const setCollection = type === 'input' ? ioSpecification.inputSets : ioSpecification.outputSets;
|
||||||
|
const index = collection.findIndex(item => item.id === entry.id);
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
const [removedElement] = collection.splice(index, 1);
|
||||||
|
setCollection.forEach(set => {
|
||||||
|
const refIndex = set[type === 'input' ? 'dataInputRefs' : 'dataOutputRefs'].indexOf(removedElement);
|
||||||
|
if (refIndex > -1) {
|
||||||
|
set[type === 'input' ? 'dataInputRefs' : 'dataOutputRefs'].splice(refIndex, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error(`No ${type === 'input' ? 'DataInput' : 'DataOutput'} found for id ${entry.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateElementProperties(commandStack, element) {
|
||||||
|
commandStack.execute('element.updateProperties', {
|
||||||
|
element: element,
|
||||||
|
moddleElement: element.businessObject,
|
||||||
|
properties: {}
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
import IoPalette from './IoPalette';
|
import IoPalette from './IoPalette';
|
||||||
import IoRules from './IoRules';
|
import IoRules from './IoRules';
|
||||||
import IoInterceptor from './IoInterceptor';
|
import IoInterceptor from './IoInterceptor';
|
||||||
|
import IoPropertiesProvider from './propertiesProvider/IoPropertiesProvider';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
__init__: [ 'IoPalette', 'IoRules', 'IoInterceptor' ],
|
__init__: [ 'IoPalette', 'IoRules', 'IoInterceptor', 'IoPropertiesProvider' ],
|
||||||
IoPalette: [ 'type', IoPalette ],
|
IoPalette: [ 'type', IoPalette ],
|
||||||
IoRules: [ 'type', IoRules ],
|
IoRules: [ 'type', IoRules ],
|
||||||
IoInterceptor: [ 'type', IoInterceptor ]
|
IoInterceptor: [ 'type', IoInterceptor ],
|
||||||
|
IoPropertiesProvider: [ 'type', IoPropertiesProvider ]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
import { useService } from 'bpmn-js-properties-panel';
|
||||||
|
import {
|
||||||
|
isTextFieldEntryEdited,
|
||||||
|
TextFieldEntry,
|
||||||
|
} from '@bpmn-io/properties-panel';
|
||||||
|
import { createSpecification, removeElementFromSpecification, updateElementProperties } from '../helpers';
|
||||||
|
|
||||||
|
export function InputParametersArray(props) {
|
||||||
|
|
||||||
|
const { element, moddle, translate, commandStack, bpmnFactory } = props;
|
||||||
|
const { businessObject } = element;
|
||||||
|
|
||||||
|
const ioSpecification = businessObject.ioSpecification;
|
||||||
|
|
||||||
|
const inputsEntries = (ioSpecification) ? ioSpecification.dataInputs : [];
|
||||||
|
|
||||||
|
const items = (inputsEntries) ? inputsEntries.map((inputEntry, index) => {
|
||||||
|
const id = `inputEntry-${index}`;
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
label: translate(inputEntry.name),
|
||||||
|
entries: InputParamGroup({
|
||||||
|
element,
|
||||||
|
commandStack,
|
||||||
|
moddle,
|
||||||
|
translate,
|
||||||
|
bpmnFactory,
|
||||||
|
inputEntry
|
||||||
|
}),
|
||||||
|
autoFocusEntry: `input-focus-entry`,
|
||||||
|
remove: removeFactory({
|
||||||
|
element, moddle, commandStack, inputEntry
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}) : [];
|
||||||
|
|
||||||
|
function add(event) {
|
||||||
|
const { businessObject } = element;
|
||||||
|
|
||||||
|
const newInputID = moddle.ids.nextPrefixed('DataInput_');
|
||||||
|
|
||||||
|
// Create a new DataInput
|
||||||
|
const newInput = bpmnFactory.create('bpmn:DataInput', { id: newInputID, name: newInputID });
|
||||||
|
|
||||||
|
// Check if ioSpecification already exists
|
||||||
|
createSpecification(bpmnFactory, businessObject, 'input', newInput)
|
||||||
|
|
||||||
|
// Update the element
|
||||||
|
updateElementProperties(commandStack, element);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { items, add };
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFactory(props) {
|
||||||
|
const { element, bpmnFactory, commandStack, inputEntry } = props;
|
||||||
|
return function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
removeElementFromSpecification(element, inputEntry, 'input');
|
||||||
|
updateElementProperties(commandStack, element);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function InputParamGroup(props) {
|
||||||
|
|
||||||
|
const { id, inputEntry, element, moddle, commandStack, translate, bpmnFactory } = props;
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
inputEntry,
|
||||||
|
component: InputParamTextField,
|
||||||
|
isEdited: isTextFieldEntryEdited,
|
||||||
|
element,
|
||||||
|
moddle,
|
||||||
|
commandStack,
|
||||||
|
translate,
|
||||||
|
bpmnFactory
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function InputParamTextField(props) {
|
||||||
|
|
||||||
|
const { id, element, inputEntry, moddle, commandStack, translate, bpmnFactory } = props;
|
||||||
|
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
|
||||||
|
const setValue = (value) => {
|
||||||
|
try {
|
||||||
|
const ioSpecification = element.businessObject.ioSpecification;
|
||||||
|
|
||||||
|
if (!value || value == '') {
|
||||||
|
console.error('No value provided for this input.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ioSpecification) {
|
||||||
|
console.error('No ioSpecification found for this element.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let existingInput = ioSpecification.dataInputs.find(input => input.id === inputEntry.name || input.name === inputEntry.name);
|
||||||
|
|
||||||
|
if (existingInput) {
|
||||||
|
existingInput.name = value;
|
||||||
|
existingInput.id = value;
|
||||||
|
} else {
|
||||||
|
console.error(`No DataInput found :> ${inputEntry.name}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateElementProperties(commandStack, element);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Setting Value Error : ', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return inputEntry.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: `${id}-input`,
|
||||||
|
label: translate('Input Name'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce,
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { ListGroup, DescriptionEntry } from '@bpmn-io/properties-panel';
|
||||||
|
import { InputParametersArray } from './InputParametersArray.js';
|
||||||
|
import { OutputParametersArray } from './OutputParametersArray.js';
|
||||||
|
|
||||||
|
export function createIoGroup(
|
||||||
|
element,
|
||||||
|
translate,
|
||||||
|
moddle,
|
||||||
|
commandStack,
|
||||||
|
bpmnFactory
|
||||||
|
) {
|
||||||
|
|
||||||
|
const group = {
|
||||||
|
label: translate('Input/Output Management'),
|
||||||
|
id: 'ioProperties',
|
||||||
|
entries: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
// add description input
|
||||||
|
group.entries.push({
|
||||||
|
id: `infos-textField`,
|
||||||
|
component: DescriptionEntry,
|
||||||
|
value:
|
||||||
|
'ℹ️ When no specific inputs/outputs are defined, all process variables are accessible.',
|
||||||
|
element,
|
||||||
|
translate,
|
||||||
|
commandStack,
|
||||||
|
});
|
||||||
|
|
||||||
|
// add input list component
|
||||||
|
group.entries.push({
|
||||||
|
id: 'inputParameters',
|
||||||
|
label: translate('Inputs'),
|
||||||
|
component: ListGroup,
|
||||||
|
...InputParametersArray({
|
||||||
|
element,
|
||||||
|
moddle,
|
||||||
|
translate,
|
||||||
|
commandStack,
|
||||||
|
bpmnFactory
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// add output list component
|
||||||
|
group.entries.push({
|
||||||
|
id: 'outputParameters',
|
||||||
|
label: translate('Outputs'),
|
||||||
|
component: ListGroup,
|
||||||
|
...OutputParametersArray({
|
||||||
|
element,
|
||||||
|
moddle,
|
||||||
|
translate,
|
||||||
|
commandStack,
|
||||||
|
bpmnFactory
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { is } from 'bpmn-js/lib/util/ModelUtil';
|
||||||
|
import { createIoGroup } from './IoGroup.js';
|
||||||
|
|
||||||
|
const LOW_PRIORITY = 500;
|
||||||
|
|
||||||
|
export default function IoPropertiesProvider(
|
||||||
|
propertiesPanel,
|
||||||
|
translate,
|
||||||
|
moddle,
|
||||||
|
commandStack,
|
||||||
|
elementRegistry,
|
||||||
|
bpmnFactory
|
||||||
|
) {
|
||||||
|
this.getGroups = function getGroupsCallback(element) {
|
||||||
|
return function pushGroup(groups) {
|
||||||
|
if (isBpmnTask(element)) {
|
||||||
|
groups.push(
|
||||||
|
createIoGroup(
|
||||||
|
element,
|
||||||
|
translate,
|
||||||
|
moddle,
|
||||||
|
commandStack,
|
||||||
|
bpmnFactory
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
propertiesPanel.registerProvider(LOW_PRIORITY, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
IoPropertiesProvider.$inject = [
|
||||||
|
'propertiesPanel',
|
||||||
|
'translate',
|
||||||
|
'moddle',
|
||||||
|
'commandStack',
|
||||||
|
'elementRegistry',
|
||||||
|
'bpmnFactory',
|
||||||
|
];
|
||||||
|
|
||||||
|
function isBpmnTask(element) {
|
||||||
|
if (!element) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
is(element, 'bpmn:UserTask') ||
|
||||||
|
is(element, 'bpmn:ScriptTask') ||
|
||||||
|
is(element, 'bpmn:ServiceTask') ||
|
||||||
|
is(element, 'bpmn:SendTask') ||
|
||||||
|
is(element, 'bpmn:ReceiveTask') ||
|
||||||
|
is(element, 'bpmn:ManualTask')
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
import { useService } from 'bpmn-js-properties-panel';
|
||||||
|
import {
|
||||||
|
isTextFieldEntryEdited,
|
||||||
|
TextFieldEntry,
|
||||||
|
} from '@bpmn-io/properties-panel';
|
||||||
|
import { createSpecification, removeElementFromSpecification, updateElementProperties } from '../helpers';
|
||||||
|
|
||||||
|
export function OutputParametersArray(props) {
|
||||||
|
|
||||||
|
const { element, moddle, translate, commandStack, bpmnFactory } = props;
|
||||||
|
const { businessObject } = element;
|
||||||
|
|
||||||
|
const ioSpecification = businessObject.ioSpecification;
|
||||||
|
|
||||||
|
const outputsEntries = (ioSpecification) ? ioSpecification.dataOutputs : [];
|
||||||
|
|
||||||
|
const items = (outputsEntries) ? outputsEntries.map((outputEntry, index) => {
|
||||||
|
const id = `outputEntry-${index}`;
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
label: translate(outputEntry.name),
|
||||||
|
entries: OutputParamGroup({
|
||||||
|
element,
|
||||||
|
commandStack,
|
||||||
|
moddle,
|
||||||
|
translate,
|
||||||
|
bpmnFactory,
|
||||||
|
outputEntry
|
||||||
|
}),
|
||||||
|
autoFocusEntry: `output-focus-entry`,
|
||||||
|
remove: removeFactory({
|
||||||
|
element, moddle, commandStack, outputEntry
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}) : [];
|
||||||
|
|
||||||
|
function add(event) {
|
||||||
|
const { businessObject } = element;
|
||||||
|
|
||||||
|
const newOutputID = moddle.ids.nextPrefixed('DataOutput_');
|
||||||
|
|
||||||
|
// Create a new DataOutput
|
||||||
|
const newOutput = bpmnFactory.create('bpmn:DataOutput', { id: newOutputID, name: newOutputID });
|
||||||
|
|
||||||
|
// Check if ioSpecification already exists
|
||||||
|
createSpecification(bpmnFactory, businessObject, 'output', newOutput)
|
||||||
|
|
||||||
|
// Update the element
|
||||||
|
updateElementProperties(commandStack, element);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { items, add };
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFactory(props) {
|
||||||
|
const { element, bpmnFactory, commandStack, outputEntry } = props;
|
||||||
|
return function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
removeElementFromSpecification(element, outputEntry, 'output');
|
||||||
|
updateElementProperties(commandStack, element);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function OutputParamGroup(props) {
|
||||||
|
|
||||||
|
const { id, outputEntry, element, moddle, commandStack, translate, bpmnFactory } = props;
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
outputEntry,
|
||||||
|
component: OutputParamTextField,
|
||||||
|
isEdited: isTextFieldEntryEdited,
|
||||||
|
element,
|
||||||
|
moddle,
|
||||||
|
commandStack,
|
||||||
|
translate,
|
||||||
|
bpmnFactory
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function OutputParamTextField(props) {
|
||||||
|
|
||||||
|
const { id, element, outputEntry, moddle, commandStack, translate, bpmnFactory } = props;
|
||||||
|
|
||||||
|
const debounce = useService('debounceInput');
|
||||||
|
|
||||||
|
const setValue = (value) => {
|
||||||
|
try {
|
||||||
|
const ioSpecification = element.businessObject.ioSpecification;
|
||||||
|
|
||||||
|
if (!value || value == '') {
|
||||||
|
console.error('No value provided for this input.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ioSpecification) {
|
||||||
|
console.error('No ioSpecification found for this element.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let existingInput = ioSpecification.dataOutputs.find(input => input.id === outputEntry.name || input.name === outputEntry.name);
|
||||||
|
|
||||||
|
if (existingInput) {
|
||||||
|
existingInput.name = value;
|
||||||
|
existingInput.id = value;
|
||||||
|
} else {
|
||||||
|
console.error(`No DataOutput found :> ${outputEntry.name}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateElementProperties(commandStack, element);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Setting Value Error : ', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getValue = () => {
|
||||||
|
return outputEntry.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextFieldEntry({
|
||||||
|
element,
|
||||||
|
id: `${id}-output`,
|
||||||
|
label: translate('Output Name'),
|
||||||
|
getValue,
|
||||||
|
setValue,
|
||||||
|
debounce,
|
||||||
|
});
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import SignalPropertiesProvider from './signals/propertiesPanel/SignalProperties
|
||||||
import ErrorPropertiesProvider from './errors/propertiesPanel/ErrorPropertiesProvider';
|
import ErrorPropertiesProvider from './errors/propertiesPanel/ErrorPropertiesProvider';
|
||||||
import EscalationPropertiesProvider from './escalations/propertiesPanel/EscalationPropertiesProvider';
|
import EscalationPropertiesProvider from './escalations/propertiesPanel/EscalationPropertiesProvider';
|
||||||
import CallActivityPropertiesProvider from './callActivity/propertiesPanel/CallActivityPropertiesProvider';
|
import CallActivityPropertiesProvider from './callActivity/propertiesPanel/CallActivityPropertiesProvider';
|
||||||
|
import IoPropertiesProvider from './InputOutput/propertiesProvider/IoPropertiesProvider';
|
||||||
import StandardLoopPropertiesProvider from './loops/StandardLoopPropertiesProvider';
|
import StandardLoopPropertiesProvider from './loops/StandardLoopPropertiesProvider';
|
||||||
import MultiInstancePropertiesProvider from './loops/MultiInstancePropertiesProvider';
|
import MultiInstancePropertiesProvider from './loops/MultiInstancePropertiesProvider';
|
||||||
import CallActivityInterceptor from './callActivity/CallActivityInterceptor';
|
import CallActivityInterceptor from './callActivity/CallActivityInterceptor';
|
||||||
|
@ -44,6 +45,7 @@ export default {
|
||||||
'dataObjectRenderer',
|
'dataObjectRenderer',
|
||||||
'multiInstancePropertiesProvider',
|
'multiInstancePropertiesProvider',
|
||||||
'standardLoopPropertiesProvider',
|
'standardLoopPropertiesProvider',
|
||||||
|
'IoPropertiesProvider',
|
||||||
'callActivityInterceptor'
|
'callActivityInterceptor'
|
||||||
],
|
],
|
||||||
dataObjectInterceptor: ['type', DataObjectInterceptor],
|
dataObjectInterceptor: ['type', DataObjectInterceptor],
|
||||||
|
@ -66,5 +68,6 @@ export default {
|
||||||
ioInterceptor: ['type', IoInterceptor],
|
ioInterceptor: ['type', IoInterceptor],
|
||||||
multiInstancePropertiesProvider: ['type', MultiInstancePropertiesProvider],
|
multiInstancePropertiesProvider: ['type', MultiInstancePropertiesProvider],
|
||||||
standardLoopPropertiesProvider: ['type', StandardLoopPropertiesProvider],
|
standardLoopPropertiesProvider: ['type', StandardLoopPropertiesProvider],
|
||||||
callActivityInterceptor: [ 'type', CallActivityInterceptor ],
|
IoPropertiesProvider: ['type', IoPropertiesProvider],
|
||||||
|
callActivityInterceptor: [ 'type', CallActivityInterceptor ]
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
import {
|
||||||
|
query as domQuery
|
||||||
|
} from 'min-dom';
|
||||||
|
import { bootstrapPropertiesPanel, CONTAINER, expectSelected, findGroupEntry } from './helpers';
|
||||||
|
import inputOutput from '../../app/spiffworkflow/InputOutput';
|
||||||
|
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||||
|
import { fireEvent } from '@testing-library/preact';
|
||||||
|
|
||||||
|
describe('BPMN Input / Output Variables', function () {
|
||||||
|
|
||||||
|
let xml = require('./bpmn/io_variables.bpmn').default;
|
||||||
|
|
||||||
|
beforeEach(bootstrapPropertiesPanel(xml, {
|
||||||
|
debounceInput: false,
|
||||||
|
additionalModules: [
|
||||||
|
inputOutput,
|
||||||
|
BpmnPropertiesPanelModule,
|
||||||
|
BpmnPropertiesProviderModule
|
||||||
|
]
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should be able to add a new input to the user task', async function () {
|
||||||
|
|
||||||
|
// We Select a userTask element
|
||||||
|
const shapeElement = await expectSelected('Activity_1hmit5k');
|
||||||
|
expect(shapeElement, "I can't find User Task element").to.exist;
|
||||||
|
|
||||||
|
// Expect shapeElement.businessObject.ioSpecification to be undefined
|
||||||
|
expect(shapeElement.businessObject.ioSpecification).to.be.undefined;
|
||||||
|
|
||||||
|
// Add new dataInput
|
||||||
|
const entry = findGroupEntry('inputParameters', CONTAINER);
|
||||||
|
let addButton = domQuery('.bio-properties-panel-add-entry', entry);
|
||||||
|
fireEvent.click(addButton);
|
||||||
|
|
||||||
|
expect(shapeElement.businessObject.ioSpecification).not.to.be.undefined;
|
||||||
|
expect(shapeElement.businessObject.ioSpecification.dataInputs.length).to.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to add a new output to the user task', async function () {
|
||||||
|
|
||||||
|
// We Select a userTask element
|
||||||
|
const shapeElement = await expectSelected('Activity_1hmit5k');
|
||||||
|
expect(shapeElement, "I can't find User Task element").to.exist;
|
||||||
|
|
||||||
|
// Expect shapeElement.businessObject.ioSpecification to be undefined
|
||||||
|
expect(shapeElement.businessObject.ioSpecification).to.be.undefined;
|
||||||
|
|
||||||
|
// Add new dataOutput
|
||||||
|
const entry = findGroupEntry('outputParameters', CONTAINER);
|
||||||
|
let addButton = domQuery('.bio-properties-panel-add-entry', entry);
|
||||||
|
fireEvent.click(addButton);
|
||||||
|
|
||||||
|
expect(shapeElement.businessObject.ioSpecification).not.to.be.undefined;
|
||||||
|
expect(shapeElement.businessObject.ioSpecification.dataOutputs.length).to.equal(1);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to delete an existing input variable from script task', async function () {
|
||||||
|
|
||||||
|
// We Select a scriptTask element
|
||||||
|
const shapeElement = await expectSelected('Activity_1dkj93x');
|
||||||
|
expect(shapeElement, "I can't find Script Task element").to.exist;
|
||||||
|
expect(shapeElement.businessObject.ioSpecification.dataInputs.length).to.equal(1);
|
||||||
|
|
||||||
|
const entry = findGroupEntry('inputParameters', CONTAINER);
|
||||||
|
let removeButton = domQuery('.bio-properties-panel-remove-entry', entry);
|
||||||
|
fireEvent.click(removeButton);
|
||||||
|
|
||||||
|
expect(shapeElement.businessObject.ioSpecification.dataInputs.length).to.equal(0);
|
||||||
|
expect(shapeElement.businessObject.ioSpecification.dataOutputs.length).to.equal(1);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
it('should be able to delete an existing output variable from script task', async function () {
|
||||||
|
|
||||||
|
// We Select a scriptTask element
|
||||||
|
const shapeElement = await expectSelected('Activity_1dkj93x');
|
||||||
|
expect(shapeElement, "I can't find Script Task element").to.exist;
|
||||||
|
expect(shapeElement.businessObject.ioSpecification.dataInputs.length).to.equal(1);
|
||||||
|
|
||||||
|
const entry = findGroupEntry('outputParameters', CONTAINER);
|
||||||
|
let removeButton = domQuery('.bio-properties-panel-remove-entry', entry);
|
||||||
|
fireEvent.click(removeButton);
|
||||||
|
|
||||||
|
expect(shapeElement.businessObject.ioSpecification.dataInputs.length).to.equal(1);
|
||||||
|
expect(shapeElement.businessObject.ioSpecification.dataOutputs.length).to.equal(0);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||||
|
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
|
||||||
|
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
|
||||||
|
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
|
||||||
|
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
|
||||||
|
xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1qnx3d3"
|
||||||
|
targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0"
|
||||||
|
modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
|
||||||
|
<bpmn:process id="Process_16xfaqc" isExecutable="true" camunda:versionTag="1">
|
||||||
|
<bpmn:startEvent id="StartEvent_1">
|
||||||
|
<bpmn:outgoing>Flow_0vt1twq</bpmn:outgoing>
|
||||||
|
</bpmn:startEvent>
|
||||||
|
<bpmn:endEvent id="Event_0yxpeto">
|
||||||
|
<bpmn:incoming>Flow_1oukz5y</bpmn:incoming>
|
||||||
|
</bpmn:endEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0vt1twq" sourceRef="StartEvent_1" targetRef="Activity_1hmit5k" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_1oukz5y" sourceRef="Activity_1dkj93x" targetRef="Event_0yxpeto" />
|
||||||
|
<bpmn:scriptTask id="Activity_1dkj93x" name="Script Task">
|
||||||
|
<bpmn:incoming>Flow_05w3wu8</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1oukz5y</bpmn:outgoing>
|
||||||
|
<bpmn:ioSpecification>
|
||||||
|
<bpmn:dataInput id="DataInput_0ab29sz" name="DataInput_0ab29sz" />
|
||||||
|
<bpmn:dataOutput id="DataOutput_1n1fg4r" name="DataOutput_1n1fg4r" />
|
||||||
|
<bpmn:inputSet>
|
||||||
|
<bpmn:dataInputRefs>DataInput_0ab29sz</bpmn:dataInputRefs>
|
||||||
|
</bpmn:inputSet>
|
||||||
|
<bpmn:outputSet>
|
||||||
|
<bpmn:dataOutputRefs>DataOutput_1n1fg4r</bpmn:dataOutputRefs>
|
||||||
|
</bpmn:outputSet>
|
||||||
|
</bpmn:ioSpecification>
|
||||||
|
</bpmn:scriptTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_05w3wu8" sourceRef="Activity_1hmit5k"
|
||||||
|
targetRef="Activity_1dkj93x" />
|
||||||
|
<bpmn:userTask id="Activity_1hmit5k" name="User task">
|
||||||
|
<bpmn:incoming>Flow_0vt1twq</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_05w3wu8</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_16xfaqc">
|
||||||
|
<bpmndi:BPMNShape id="Event_0yxpeto_di" bpmnElement="Event_0yxpeto">
|
||||||
|
<dc:Bounds x="422" y="82" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
|
<dc:Bounds x="12" y="82" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1viyuct_di" bpmnElement="Activity_1hmit5k">
|
||||||
|
<dc:Bounds x="110" y="60" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1ywbcwu_di" bpmnElement="Activity_1dkj93x">
|
||||||
|
<dc:Bounds x="270" y="60" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0vt1twq_di" bpmnElement="Flow_0vt1twq">
|
||||||
|
<di:waypoint x="48" y="100" />
|
||||||
|
<di:waypoint x="110" y="100" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1oukz5y_di" bpmnElement="Flow_1oukz5y">
|
||||||
|
<di:waypoint x="370" y="100" />
|
||||||
|
<di:waypoint x="422" y="100" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_05w3wu8_di" bpmnElement="Flow_05w3wu8">
|
||||||
|
<di:waypoint x="210" y="100" />
|
||||||
|
<di:waypoint x="270" y="100" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn:definitions>
|
Loading…
Reference in New Issue