Squashed 'bpmn-js-spiffworkflow/' changes from 6007a770a..9762eb631
9762eb631 updated data object category to just category 2169b54d3 Merge pull request #58 from sartography/feature/data-object-category 1816c7f08 fixed tests w/ burnettk d888c37b0 added support to add categories to data objects in extensions w/ burnettk b00abf00c Merge pull request #57 from sartography/feature/dataObject-naming-with-dataState ae4bd8154 Fix Overrided Label editing provider bug bfbfb0106 Merge pull request #56 from sartography/enhancements/condition-expression 3b4f06b8c Switch from TextField to textAreaFieal ec81cfa0b Done with basic unic testing 9c1d9afac Implement new tests 123037d8e Before implementing new tests 84a0667ec Remove Consoles 511a9c9c3 Done with Fixing Broken Tests 37e71bdef Handle Broken Tests 5 7aa03cd39 Handle Broken Test 4 80dcc92d2 Handle Broken Tests 3 d3a1f3825 Handle Broken Tests 2 e598f86fe Broken Tests 5289bd6ee Add Rename references to dataObjectHelpers cc2482ad4 Handle Manual Changes f3d5a94c9 Add LabelEditing Provider ab311a29f NPM RUN LINT 39d0cf616 Before Implement Manual Change 84d6e20ff OnChange Events e35578061 Remove Name Input ee68f07f2 Update reference name on change dataObj Name 845c3edc4 INNIT eae58f559 Merge pull request #53 from sartography/feature/data-store-props aa6640e38 Ready To Deploy 2778c764f Last a368d0cec Feature is implemented 3d757eca9 Add Interceptors d1fe1d2b2 Remove duplicate group f0e98ceea Merging cd6546d3e Add bpmn:dataStore in the level of process definition 2a4c1ffc6 linting. 71cf495df Implement Tests c1dbb1599 Merge pull request #51 from sartography/dependabot/github_actions/JS-DevTools/npm-publish-3 5460f57fd Merge pull request #52 from sartography/dependabot/github_actions/actions/setup-node-4 eedab6e82 Bump actions/setup-node from 3 to 4 04186b903 Merge pull request #48 from sartography/feature/add-conditional-events 10bcfce4f No param sort (#50) 025f428cd Bump JS-DevTools/npm-publish from 2 to 3 4d160b8cb display condition panel for conditional events and inclusive gateway sources git-subtree-dir: bpmn-js-spiffworkflow git-subtree-split: 9762eb631de107aac584fce1c056070cdaed171e
This commit is contained in:
parent
392c9a1b44
commit
9273e6425b
|
@ -13,12 +13,12 @@ jobs:
|
|||
steps:
|
||||
|
||||
- uses: actions/checkout@v4 #Checkout Repo
|
||||
- uses: actions/setup-node@v3 #Setup Node
|
||||
- uses: actions/setup-node@v4 #Setup Node
|
||||
with:
|
||||
node-version: 18
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
- uses: JS-DevTools/npm-publish@v2
|
||||
- uses: JS-DevTools/npm-publish@v3
|
||||
with:
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
access: public
|
||||
|
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4 #Checkout Repo
|
||||
- uses: actions/setup-node@v3 #Setup Node
|
||||
- uses: actions/setup-node@v4 #Setup Node
|
||||
- uses: nanasess/setup-chromedriver@v2 #Setup ChromeDriver
|
||||
with:
|
||||
node-version: '18'
|
||||
|
|
|
@ -179,6 +179,15 @@ bpmnModeler.on('spiff.dmn_files.requested', (event) => {
|
|||
});
|
||||
});
|
||||
|
||||
bpmnModeler.on('spiff.data_stores.requested', (event) => {
|
||||
event.eventBus.fire('spiff.data_stores.returned', {
|
||||
options: [
|
||||
{ type: 'typeahead', name: 'countries' },
|
||||
{ type: 'kkv', name: 'foods' }
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
// As call activites might refernce processes across the system
|
||||
// it should be possible to search for a paticular call activity.
|
||||
bpmnModeler.on('spiff.callactivity.search', (event) => {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
export function findDataObjects(parent, dataObjects) {
|
||||
if (typeof(dataObjects) === 'undefined')
|
||||
if (typeof (dataObjects) === 'undefined')
|
||||
dataObjects = [];
|
||||
let process;
|
||||
if (!parent) {
|
||||
|
@ -18,7 +18,7 @@ export function findDataObjects(parent, dataObjects) {
|
|||
if (process.$type === 'bpmn:SubProcess')
|
||||
findDataObjects(process.$parent, dataObjects);
|
||||
}
|
||||
if (typeof(process.flowElements) !== 'undefined') {
|
||||
if (typeof (process.flowElements) !== 'undefined') {
|
||||
for (const element of process.flowElements) {
|
||||
if (element.$type === 'bpmn:DataObject')
|
||||
dataObjects.push(element);
|
||||
|
@ -68,3 +68,19 @@ export function idToHumanReadableName(id) {
|
|||
return word.charAt(0).toUpperCase() + word.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
export function updateDataObjectReferencesName(parent, nameValue, dataObjectId, commandStack) {
|
||||
const references = findDataObjectReferenceShapes(parent.children, dataObjectId);
|
||||
for (const ref of references) {
|
||||
const stateName = ref.businessObject.dataState && ref.businessObject.dataState.name ? ref.businessObject.dataState.name : '';
|
||||
const newName = stateName ? `${nameValue} [${stateName}]` : nameValue;
|
||||
commandStack.execute('element.updateProperties', {
|
||||
element: ref,
|
||||
moddleElement: ref.businessObject,
|
||||
properties: {
|
||||
name: newName,
|
||||
},
|
||||
changed: [ref],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ export default class DataObjectInterceptor extends CommandInterceptor {
|
|||
dataObject = existingDataObjects[0];
|
||||
} else {
|
||||
dataObject = bpmnFactory.create('bpmn:DataObject');
|
||||
dataObject.name = idToHumanReadableName(dataObject.id);
|
||||
}
|
||||
// set the reference to the DataObject
|
||||
shape.businessObject.dataObjectRef = dataObject;
|
||||
|
@ -107,7 +108,7 @@ export default class DataObjectInterceptor extends CommandInterceptor {
|
|||
element: shape,
|
||||
moddleElement: shape.businessObject,
|
||||
properties: {
|
||||
name: idToHumanReadableName(shape.businessObject.dataObjectRef.id),
|
||||
name: shape.businessObject.dataObjectRef.name,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -137,6 +138,7 @@ export default class DataObjectInterceptor extends CommandInterceptor {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import { is } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import { findDataObject, updateDataObjectReferencesName } from './DataObjectHelpers';
|
||||
|
||||
export default function DataObjectLabelEditingProvider(eventBus, directEditing, commandStack, modeling) {
|
||||
|
||||
let el;
|
||||
|
||||
// listen to dblclick on non-root elements
|
||||
eventBus.on('element.dblclick', function (event) {
|
||||
const { element } = event;
|
||||
if (is(element.businessObject, 'bpmn:DataObjectReference')) {
|
||||
let label = element.businessObject.name;
|
||||
label = label.replace(/\s*\[.*?\]\s*$/, '');
|
||||
modeling.updateLabel(element, label);
|
||||
directEditing.activate(element);
|
||||
el = element;
|
||||
}
|
||||
});
|
||||
|
||||
eventBus.on('directEditing.complete', function (event) {
|
||||
|
||||
const element = el;
|
||||
|
||||
if (element && is(element.businessObject, 'bpmn:DataObjectReference')) {
|
||||
|
||||
setTimeout(() => {
|
||||
const process = element.parent.businessObject;
|
||||
const dataObject = findDataObject(process, element.businessObject.dataObjectRef.id);
|
||||
const dataState = element.businessObject.dataState && element.businessObject.dataState.name;
|
||||
|
||||
let newLabel = element.businessObject.name;
|
||||
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: dataObject,
|
||||
properties: {
|
||||
name: newLabel,
|
||||
},
|
||||
});
|
||||
|
||||
// Update references name
|
||||
updateDataObjectReferencesName(element.parent, newLabel, dataObject.id, commandStack);
|
||||
|
||||
// Append the data state if it exists
|
||||
if (dataState) {
|
||||
newLabel += ` [${dataState}]`;
|
||||
}
|
||||
|
||||
// Update the label with the data state
|
||||
modeling.updateLabel(element, newLabel);
|
||||
el = undefined;
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DataObjectLabelEditingProvider.$inject = [
|
||||
'eventBus',
|
||||
'directEditing',
|
||||
'commandStack',
|
||||
'modeling'
|
||||
];
|
|
@ -3,17 +3,18 @@ import DataObjectRules from './DataObjectRules';
|
|||
import RulesModule from 'diagram-js/lib/features/rules';
|
||||
import DataObjectRenderer from './DataObjectRenderer';
|
||||
import DataObjectPropertiesProvider from './propertiesPanel/DataObjectPropertiesProvider';
|
||||
|
||||
import DataObjectLabelEditingProvider from './DataObjectLabelEditingProvider';
|
||||
|
||||
export default {
|
||||
__depends__: [
|
||||
RulesModule
|
||||
],
|
||||
__init__: [ 'dataInterceptor', 'dataObjectRules', 'dataObjectRenderer', 'dataObjectPropertiesProvider' ],
|
||||
__init__: [ 'dataInterceptor', 'dataObjectRules', 'dataObjectRenderer', 'dataObjectPropertiesProvider', 'dataObjectLabelEditingProvider' ],
|
||||
dataInterceptor: [ 'type', DataObjectInterceptor ],
|
||||
dataObjectRules: [ 'type', DataObjectRules ],
|
||||
dataObjectRenderer: [ 'type', DataObjectRenderer ],
|
||||
dataObjectPropertiesProvider: [ 'type', DataObjectPropertiesProvider ]
|
||||
dataObjectPropertiesProvider: [ 'type', DataObjectPropertiesProvider ],
|
||||
dataObjectLabelEditingProvider: [ 'type', DataObjectLabelEditingProvider ]
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { useService } from 'bpmn-js-properties-panel';
|
||||
import {SpiffExtensionTextInput} from '../../extensions/propertiesPanel/SpiffExtensionTextInput';
|
||||
import {
|
||||
isTextFieldEntryEdited,
|
||||
TextFieldEntry,
|
||||
|
@ -8,7 +9,9 @@ import { is } from 'bpmn-js/lib/util/ModelUtil';
|
|||
import {
|
||||
findDataObjects,
|
||||
findDataObjectReferenceShapes,
|
||||
updateDataObjectReferencesName,
|
||||
idToHumanReadableName,
|
||||
findDataObject,
|
||||
} from '../DataObjectHelpers';
|
||||
|
||||
/**
|
||||
|
@ -40,6 +43,8 @@ export function DataObjectArray(props) {
|
|||
idPrefix: id,
|
||||
element,
|
||||
dataObject,
|
||||
commandStack,
|
||||
moddle,
|
||||
}),
|
||||
autoFocusEntry: `${id}-dataObject`,
|
||||
remove: removeFactory({
|
||||
|
@ -57,6 +62,7 @@ export function DataObjectArray(props) {
|
|||
const newDataObject = moddle.create('bpmn:DataObject');
|
||||
const newElements = process.get('flowElements');
|
||||
newDataObject.id = moddle.ids.nextPrefixed('DataObject_');
|
||||
newDataObject.name = idToHumanReadableName(newDataObject.id);
|
||||
newDataObject.$parent = process;
|
||||
newElements.push(newDataObject);
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
|
@ -92,7 +98,7 @@ function removeFactory(props) {
|
|||
}
|
||||
|
||||
function DataObjectGroup(props) {
|
||||
const { idPrefix, dataObject } = props;
|
||||
const { idPrefix, dataObject, element, moddle, commandStack } = props;
|
||||
|
||||
return [
|
||||
{
|
||||
|
@ -102,6 +108,22 @@ function DataObjectGroup(props) {
|
|||
idPrefix,
|
||||
dataObject,
|
||||
},
|
||||
{
|
||||
id: `${idPrefix}-dataObjectName`,
|
||||
component: DataObjectNameTextField,
|
||||
isEdited: isTextFieldEntryEdited,
|
||||
idPrefix,
|
||||
dataObject,
|
||||
},
|
||||
{
|
||||
businessObject: dataObject,
|
||||
commandStack: commandStack,
|
||||
moddle: moddle,
|
||||
component: SpiffExtensionTextInput,
|
||||
name: 'spiffworkflow:Category',
|
||||
label: 'Data Object Category',
|
||||
description: 'Useful for setting permissions on groups of data objects.',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -112,25 +134,26 @@ function DataObjectTextField(props) {
|
|||
const debounce = useService('debounceInput');
|
||||
|
||||
const setValue = (value) => {
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: dataObject,
|
||||
properties: {
|
||||
id: value,
|
||||
},
|
||||
});
|
||||
try {
|
||||
// Check if new dataObject Id is not unique
|
||||
if(findDataObject(element.businessObject, value) !== undefined){
|
||||
alert('Data Object ID Should be unique');
|
||||
return;
|
||||
}
|
||||
|
||||
// Also update the label of all the references
|
||||
const references = findDataObjectReferenceShapes(element.children, dataObject.id);
|
||||
for (const ref of references) {
|
||||
commandStack.execute('element.updateProperties', {
|
||||
element: ref,
|
||||
moddleElement: ref.businessObject,
|
||||
// let doName = idToHumanReadableName(value);
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: dataObject,
|
||||
properties: {
|
||||
name: idToHumanReadableName(value),
|
||||
id: value,
|
||||
// name: doName
|
||||
},
|
||||
changed: [ref], // everything is already marked as changed, don't recalculate.
|
||||
});
|
||||
// Update references name
|
||||
// updateDataObjectReferencesName(element, doName, value, commandStack);
|
||||
} catch (error) {
|
||||
console.log('Set Value Error : ', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -147,3 +170,38 @@ function DataObjectTextField(props) {
|
|||
debounce,
|
||||
});
|
||||
}
|
||||
|
||||
function DataObjectNameTextField(props) {
|
||||
const { idPrefix, element, parameter, dataObject } = props;
|
||||
|
||||
const commandStack = useService('commandStack');
|
||||
const debounce = useService('debounceInput');
|
||||
|
||||
const setValue = (value) => {
|
||||
|
||||
// Update references name
|
||||
updateDataObjectReferencesName(element, value, dataObject.id, commandStack);
|
||||
|
||||
// Update dataObject name
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: dataObject,
|
||||
properties: {
|
||||
name: value,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const getValue = () => {
|
||||
return dataObject.name;
|
||||
};
|
||||
|
||||
return TextFieldEntry({
|
||||
element: parameter,
|
||||
id: `${idPrefix}-name`,
|
||||
label: 'Data Object Name',
|
||||
getValue,
|
||||
setValue,
|
||||
debounce,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { is, isAny } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import { ListGroup, isTextFieldEntryEdited } from '@bpmn-io/properties-panel';
|
||||
import { ListGroup, isTextFieldEntryEdited, TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
import { DataObjectSelect } from './DataObjectSelect';
|
||||
import { DataObjectArray } from './DataObjectArray';
|
||||
import { useService } from 'bpmn-js-properties-panel';
|
||||
|
||||
const LOW_PRIORITY = 500;
|
||||
|
||||
|
@ -10,13 +11,20 @@ export default function DataObjectPropertiesProvider(
|
|||
translate,
|
||||
moddle,
|
||||
commandStack,
|
||||
elementRegistry
|
||||
elementRegistry,
|
||||
modeling,
|
||||
bpmnFactory
|
||||
) {
|
||||
this.getGroups = function (element) {
|
||||
return function (groups) {
|
||||
if (is(element, 'bpmn:DataObjectReference')) {
|
||||
const generalGroup = groups.find(group => group.id === 'general');
|
||||
if (generalGroup) {
|
||||
generalGroup.entries = generalGroup.entries.filter(entry => entry.id !== 'name');
|
||||
}
|
||||
|
||||
groups.push(
|
||||
createDataObjectSelector(element, translate, moddle, commandStack)
|
||||
createDataObjectSelector(element, translate, moddle, commandStack, modeling, bpmnFactory)
|
||||
);
|
||||
}
|
||||
if (
|
||||
|
@ -45,6 +53,8 @@ DataObjectPropertiesProvider.$inject = [
|
|||
'moddle',
|
||||
'commandStack',
|
||||
'elementRegistry',
|
||||
'modeling',
|
||||
'bpmnFactory'
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -54,7 +64,7 @@ DataObjectPropertiesProvider.$inject = [
|
|||
* @param moddle
|
||||
* @returns entries
|
||||
*/
|
||||
function createDataObjectSelector(element, translate, moddle, commandStack) {
|
||||
function createDataObjectSelector(element, translate, moddle, commandStack, modeling, bpmnFactory) {
|
||||
return {
|
||||
id: 'data_object_properties',
|
||||
label: translate('Data Object Properties'),
|
||||
|
@ -67,6 +77,15 @@ function createDataObjectSelector(element, translate, moddle, commandStack) {
|
|||
moddle,
|
||||
commandStack,
|
||||
},
|
||||
{
|
||||
id: 'selectDataState',
|
||||
element,
|
||||
component: createDataStateTextField,
|
||||
moddle,
|
||||
commandStack,
|
||||
modeling,
|
||||
bpmnFactory
|
||||
}
|
||||
],
|
||||
};
|
||||
}
|
||||
|
@ -98,3 +117,61 @@ function createDataObjectEditor(
|
|||
return dataObjectArray;
|
||||
}
|
||||
}
|
||||
|
||||
function createDataStateTextField(props) {
|
||||
const { id, element, commandStack, modeling, bpmnFactory } = props;
|
||||
|
||||
const debounce = useService('debounceInput');
|
||||
|
||||
const setValue = (value) => {
|
||||
const businessObject = element.businessObject;
|
||||
|
||||
// Check if the element is a DataObjectReference
|
||||
if (!is(businessObject, 'bpmn:DataObjectReference')) {
|
||||
console.error('The element is not a DataObjectReference.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new DataState or update the existing one
|
||||
let dataState = businessObject.dataState;
|
||||
if (!dataState) {
|
||||
dataState = bpmnFactory.create('bpmn:DataState', {
|
||||
id: 'DataState_' + businessObject.id,
|
||||
name: value
|
||||
});
|
||||
} else {
|
||||
dataState.name = value;
|
||||
}
|
||||
|
||||
// Update the DataObjectReference with new or updated DataState
|
||||
modeling.updateProperties(element, {
|
||||
dataState: dataState
|
||||
});
|
||||
|
||||
// Extract the original name
|
||||
const originalName = businessObject.name.split(' [')[0];
|
||||
|
||||
// Update the label of the DataObjectReference
|
||||
const newName = (value) ? originalName + ' [' + value + ']' : originalName;
|
||||
|
||||
modeling.updateProperties(element, {
|
||||
name: newName
|
||||
});
|
||||
};
|
||||
|
||||
const getValue = () => {
|
||||
const businessObject = element.businessObject;
|
||||
return businessObject.dataState ? businessObject.dataState.name : '';
|
||||
};
|
||||
|
||||
return TextFieldEntry({
|
||||
element,
|
||||
id: `${id}-textField`,
|
||||
name: 'spiffworkflow:DataStateLabel',
|
||||
label: 'What is the state of this reference?',
|
||||
description: 'Enter the Data State for this reference.',
|
||||
getValue,
|
||||
setValue,
|
||||
debounce,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {useService } from 'bpmn-js-properties-panel';
|
||||
import { useService } from 'bpmn-js-properties-panel';
|
||||
import { SelectEntry } from '@bpmn-io/properties-panel';
|
||||
import {findDataObjects, idToHumanReadableName} from '../DataObjectHelpers';
|
||||
import { findDataObjects } from '../DataObjectHelpers';
|
||||
|
||||
/**
|
||||
* Finds the value of the given type within the extensionElements
|
||||
|
@ -32,20 +32,25 @@ export function DataObjectSelect(props) {
|
|||
const setValue = value => {
|
||||
const businessObject = element.businessObject;
|
||||
const dataObjects = findDataObjects(businessObject.$parent)
|
||||
for (const flowElem of dataObjects) {
|
||||
if (flowElem.$type === 'bpmn:DataObject' && flowElem.id === value) {
|
||||
for (const dataObject of dataObjects) {
|
||||
if (dataObject.$type === 'bpmn:DataObject' && dataObject.id === value) {
|
||||
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
element: element,
|
||||
moddleElement: businessObject,
|
||||
properties: {
|
||||
dataObjectRef: flowElem
|
||||
dataObjectRef: dataObject
|
||||
}
|
||||
});
|
||||
|
||||
// Construct the new name by : the dataObject name and the current state
|
||||
const stateName = businessObject.dataState && businessObject.dataState.name ? businessObject.dataState.name : '';
|
||||
const newName = stateName ? `${dataObject.name} [${stateName}]` : dataObject.name;
|
||||
// Update the name property of the DataObjectReference
|
||||
commandStack.execute('element.updateProperties', {
|
||||
element,
|
||||
moddleElement: businessObject,
|
||||
element: element,
|
||||
properties: {
|
||||
'name': idToHumanReadableName(flowElem.id)
|
||||
name: newName
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -58,7 +63,7 @@ export function DataObjectSelect(props) {
|
|||
let dataObjects = findDataObjects(parent);
|
||||
let options = [];
|
||||
dataObjects.forEach(dataObj => {
|
||||
options.push({label: dataObj.id, value: dataObj.id})
|
||||
options.push({ label: dataObj.id, value: dataObj.id })
|
||||
});
|
||||
return options;
|
||||
}
|
||||
|
@ -68,9 +73,9 @@ export function DataObjectSelect(props) {
|
|||
element={element}
|
||||
description={"Select the Data Object this represents."}
|
||||
label={"Which Data Object does this reference?"}
|
||||
getValue={ getValue }
|
||||
setValue={ setValue }
|
||||
getOptions={ getOptions }
|
||||
getValue={getValue}
|
||||
setValue={setValue}
|
||||
getOptions={getOptions}
|
||||
debounce={debounce}
|
||||
/>;
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
export function isDataStoreReferenced(process, dataStoreId) {
|
||||
const status = process.get('flowElements').some(elem =>
|
||||
elem.$type === 'bpmn:DataStoreReference' && elem.dataStoreRef && elem.dataStoreRef.id === dataStoreId
|
||||
);
|
||||
return status;
|
||||
}
|
||||
|
||||
export function isDataStoreReferencedV2(definitions, dataStoreId) {
|
||||
return definitions.get('rootElements').some(elem =>
|
||||
elem.$type === 'bpmn:DataStoreReference' && elem.dataStoreRef && elem.dataStoreRef.id === dataStoreId
|
||||
);
|
||||
}
|
||||
|
||||
export function removeDataStore(definitions, dataStoreId) {
|
||||
definitions.set('rootElements', definitions.get('rootElements').filter(elem =>
|
||||
!(elem.$type === 'bpmn:DataStore' && elem.id === dataStoreId)
|
||||
));
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
||||
import { getDi, is } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import { isDataStoreReferenced, removeDataStore } from './DataStoreHelpers';
|
||||
|
||||
const HIGH_PRIORITY = 1500;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default class DataStoreInterceptor extends CommandInterceptor {
|
||||
|
||||
constructor(eventBus, bpmnFactory, commandStack, bpmnUpdater) {
|
||||
super(eventBus);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
// bpmnUpdater.updateSemanticParent = (businessObject, parentBusinessObject) => {
|
||||
// if (is(businessObject, 'bpmn:DataStoreReference')) {
|
||||
// console.log('updateSemanticParent', businessObject, parentBusinessObject);
|
||||
// bpmnUpdater.__proto__.updateSemanticParent.call(bpmnUpdater, businessObject, parentBusinessObject);
|
||||
// }
|
||||
// };
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
// this.preExecute(['shape.create'], HIGH_PRIORITY, function (event) {
|
||||
// const { context } = event;
|
||||
// const { shape } = context;
|
||||
// if (is(shape, 'bpmn:DataStoreReference') && shape.type !== 'label') {
|
||||
// // event.stopPropagation();*
|
||||
// console.log('preExecute shape.create', shape, context);
|
||||
// }
|
||||
// });
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
// this.executed(['shape.create'], HIGH_PRIORITY, function (event) {
|
||||
// const { context } = event;
|
||||
// const { shape } = context;
|
||||
// if (is(shape, 'bpmn:DataStoreReference') && shape.type !== 'label') {
|
||||
// console.log('executed shape.create', shape, context);
|
||||
// }
|
||||
// });
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
// this.postExecuted(['shape.create'], HIGH_PRIORITY, function (event) {
|
||||
// const { context } = event;
|
||||
// const { shape } = context;
|
||||
// if (is(shape, 'bpmn:DataStoreReference') && shape.type !== 'label') {
|
||||
// console.log('postExecuted shape.create', shape, context);
|
||||
// }
|
||||
// });
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
this.postExecuted(['shape.delete'], HIGH_PRIORITY, function (event) {
|
||||
const { context } = event;
|
||||
const { shape } = context;
|
||||
|
||||
if (is(shape, 'bpmn:DataStoreReference') && shape.type !== 'label') {
|
||||
const definitions = context.oldParent.businessObject.$parent;
|
||||
const dataStore = shape.businessObject.dataStoreRef;
|
||||
if (dataStore && !isDataStoreReferenced(context.oldParent.businessObject, dataStore.id)) {
|
||||
// Remove datastore if it's not linked with another datastore ref
|
||||
removeDataStore(definitions, dataStore.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
DataStoreInterceptor.$inject = ['eventBus', 'bpmnFactory', 'commandStack', 'bpmnUpdater'];
|
|
@ -0,0 +1,12 @@
|
|||
import RulesModule from 'diagram-js/lib/features/rules';
|
||||
import DataStorePropertiesProvider from './propertiesPanel/DataStorePropertiesProvider';
|
||||
import DataStoreInterceptor from './DataStoreInterceptor';
|
||||
|
||||
export default {
|
||||
__depends__: [
|
||||
RulesModule
|
||||
],
|
||||
__init__: [ 'dataStoreInterceptor', 'dataStorePropertiesProvider' ],
|
||||
dataStoreInterceptor: [ 'type', DataStoreInterceptor ],
|
||||
dataStorePropertiesProvider: [ 'type', DataStorePropertiesProvider ]
|
||||
};
|
|
@ -0,0 +1,74 @@
|
|||
import { is } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import { DataStoreSelect, OPTION_TYPE } from './DataStoreSelect';
|
||||
|
||||
const LOW_PRIORITY = 500;
|
||||
|
||||
export default function DataStorePropertiesProvider(
|
||||
modeling,
|
||||
propertiesPanel,
|
||||
translate,
|
||||
moddle,
|
||||
commandStack,
|
||||
bpmnFactory,
|
||||
) {
|
||||
this.getGroups = function (element) {
|
||||
return function (groups) {
|
||||
if (is(element, 'bpmn:DataStoreReference')) {
|
||||
groups.push(
|
||||
createCustomDataStoreGroup(
|
||||
modeling,
|
||||
element,
|
||||
translate,
|
||||
moddle,
|
||||
commandStack,
|
||||
bpmnFactory
|
||||
)
|
||||
);
|
||||
}
|
||||
return groups;
|
||||
};
|
||||
};
|
||||
propertiesPanel.registerProvider(LOW_PRIORITY, this);
|
||||
}
|
||||
|
||||
DataStorePropertiesProvider.$inject = [
|
||||
'modeling',
|
||||
'propertiesPanel',
|
||||
'translate',
|
||||
'moddle',
|
||||
'commandStack',
|
||||
'bpmnFactory',
|
||||
];
|
||||
|
||||
function createCustomDataStoreGroup(
|
||||
modeling,
|
||||
element,
|
||||
translate,
|
||||
moddle,
|
||||
commandStack,
|
||||
bpmnFactory
|
||||
) {
|
||||
const group = {
|
||||
label: translate('Custom Data Store Properties'),
|
||||
id: 'custom-datastore-properties',
|
||||
entries: [],
|
||||
};
|
||||
|
||||
// other custom properties as needed
|
||||
group.entries.push({
|
||||
id: 'selectDataStore',
|
||||
element,
|
||||
component: DataStoreSelect,
|
||||
optionType: OPTION_TYPE.data_stores,
|
||||
moddle,
|
||||
commandStack,
|
||||
translate,
|
||||
name: 'dataStoreRef',
|
||||
label: translate('Select DataSource'),
|
||||
description: translate('Select a datasource from the list'),
|
||||
modeling,
|
||||
bpmnFactory,
|
||||
});
|
||||
|
||||
return group;
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
import { useService } from 'bpmn-js-properties-panel';
|
||||
import { SelectEntry } from '@bpmn-io/properties-panel';
|
||||
import { isDataStoreReferenced, removeDataStore } from '../DataStoreHelpers';
|
||||
|
||||
export const OPTION_TYPE = {
|
||||
data_stores: 'data_stores',
|
||||
};
|
||||
|
||||
export const spiffExtensionOptions = {};
|
||||
|
||||
export function DataStoreSelect(props) {
|
||||
|
||||
const { id, label, description, optionType } = props;
|
||||
|
||||
const { element } = props;
|
||||
const { commandStack } = props;
|
||||
const { modeling } = props;
|
||||
|
||||
const debounce = useService('debounceInput');
|
||||
const eventBus = useService('eventBus');
|
||||
const bpmnFactory = useService('bpmnFactory');
|
||||
|
||||
const getValue = () => {
|
||||
return element.businessObject.dataStoreRef
|
||||
? element.businessObject.dataStoreRef.id
|
||||
: '';
|
||||
};
|
||||
|
||||
const setValue = (value) => {
|
||||
if (!value || value == '') {
|
||||
modeling.updateProperties(element, {
|
||||
dataStoreRef: null,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Add DataStore to the BPMN model
|
||||
const process = element.businessObject.$parent;
|
||||
const definitions = process.$parent;
|
||||
if (!definitions.get('rootElements')) {
|
||||
definitions.set('rootElements', []);
|
||||
}
|
||||
|
||||
// Persist Current DataStore Ref
|
||||
const currentDataStoreRef = element.businessObject.dataStoreRef;
|
||||
|
||||
// Create DataStore
|
||||
let dataStore = definitions.get('rootElements').find(element =>
|
||||
element.$type === 'bpmn:DataStore' && element.id === value
|
||||
);
|
||||
|
||||
// If the DataStore doesn't exist, create new one
|
||||
if (!dataStore) {
|
||||
dataStore = bpmnFactory.create('bpmn:DataStore', {
|
||||
id: value,
|
||||
name: 'DataStore_' + value
|
||||
});
|
||||
definitions.get('rootElements').push(dataStore);
|
||||
}
|
||||
|
||||
modeling.updateProperties(element, {
|
||||
dataStoreRef: dataStore,
|
||||
});
|
||||
|
||||
// Remove the old DataStore if it's no longer referenced
|
||||
if (currentDataStoreRef && !isDataStoreReferenced(process, currentDataStoreRef.id)) {
|
||||
removeDataStore(definitions, currentDataStoreRef.id);
|
||||
}
|
||||
};
|
||||
|
||||
if (
|
||||
!(optionType in spiffExtensionOptions) ||
|
||||
spiffExtensionOptions[optionType] === null
|
||||
) {
|
||||
spiffExtensionOptions[optionType] = null;
|
||||
requestOptions(eventBus, element, commandStack, optionType);
|
||||
}
|
||||
|
||||
const getOptions = () => {
|
||||
const optionList = [];
|
||||
optionList.push({
|
||||
label: '',
|
||||
value: '',
|
||||
});
|
||||
if (
|
||||
optionType in spiffExtensionOptions &&
|
||||
spiffExtensionOptions[optionType] !== null
|
||||
) {
|
||||
spiffExtensionOptions[optionType].forEach((opt) => {
|
||||
optionList.push({
|
||||
label: opt.name,
|
||||
value: opt.name,
|
||||
});
|
||||
});
|
||||
}
|
||||
return optionList;
|
||||
};
|
||||
|
||||
return SelectEntry({
|
||||
id,
|
||||
element,
|
||||
label,
|
||||
description,
|
||||
getValue,
|
||||
setValue,
|
||||
getOptions,
|
||||
debounce,
|
||||
});
|
||||
}
|
||||
|
||||
function requestOptions(eventBus, element, commandStack, optionType) {
|
||||
eventBus.on(`spiff.${optionType}.returned`, (event) => {
|
||||
spiffExtensionOptions[optionType] = event.options;
|
||||
});
|
||||
eventBus.fire(`spiff.${optionType}.requested`, { eventBus });
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import { is } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import {
|
||||
isTextFieldEntryEdited,
|
||||
TextFieldEntry,
|
||||
TextAreaEntry
|
||||
} from '@bpmn-io/properties-panel';
|
||||
import { useService } from 'bpmn-js-properties-panel';
|
||||
|
||||
|
@ -18,7 +17,14 @@ export default function ConditionsPropertiesProvider(
|
|||
return function pushGroup(groups) {
|
||||
if (is(element, 'bpmn:SequenceFlow')) {
|
||||
const { source } = element;
|
||||
if (is(source, 'bpmn:ExclusiveGateway')) {
|
||||
if (is(source, 'bpmn:ExclusiveGateway') || is(source, 'bpmn:InclusiveGateway')) {
|
||||
groups.push(
|
||||
createConditionsGroup(element, translate, moddle, commandStack)
|
||||
);
|
||||
}
|
||||
} else if (is(element, 'bpmn:Event')) {
|
||||
const eventDefinitions = element.businessObject.eventDefinitions;
|
||||
if (eventDefinitions.filter(ev => is(ev, 'bpmn:ConditionalEventDefinition')).length > 0) {
|
||||
groups.push(
|
||||
createConditionsGroup(element, translate, moddle, commandStack)
|
||||
);
|
||||
|
@ -73,7 +79,13 @@ function ConditionExpressionTextField(props) {
|
|||
|
||||
const debounce = useService('debounceInput');
|
||||
const getValue = () => {
|
||||
const { conditionExpression } = element.businessObject;
|
||||
let conditionExpression;
|
||||
if (is(element, 'bpmn:SequenceFlow')) {
|
||||
conditionExpression = element.businessObject.conditionExpression;
|
||||
} else if (is(element, 'bpmn:Event')) {
|
||||
const eventDef = element.businessObject.eventDefinitions.find(ev => is(ev, 'bpmn:ConditionalEventDefinition'));
|
||||
conditionExpression = eventDef.condition;
|
||||
}
|
||||
if (conditionExpression) {
|
||||
return conditionExpression.body;
|
||||
}
|
||||
|
@ -86,11 +98,15 @@ function ConditionExpressionTextField(props) {
|
|||
conditionExpressionModdleElement = moddle.create('bpmn:Expression');
|
||||
}
|
||||
conditionExpressionModdleElement.body = value;
|
||||
element.businessObject.conditionExpression =
|
||||
conditionExpressionModdleElement;
|
||||
if (is(element, 'bpmn:SequenceFlow')) {
|
||||
element.businessObject.conditionExpression = conditionExpressionModdleElement;
|
||||
} else if (is(element, 'bpmn:Event')) {
|
||||
const eventDef = element.businessObject.eventDefinitions.find(ev => is(ev, 'bpmn:ConditionalEventDefinition'));
|
||||
eventDef.condition = conditionExpressionModdleElement;
|
||||
}
|
||||
};
|
||||
|
||||
return TextFieldEntry({
|
||||
return TextAreaEntry({
|
||||
element,
|
||||
id: `the-id`,
|
||||
label,
|
||||
|
|
|
@ -33,14 +33,14 @@ const PREFIX = 'spiffworkflow:';
|
|||
* @param element
|
||||
* @param name
|
||||
*/
|
||||
export function getExtensionValue(element, name) {
|
||||
export function getExtensionValue(businessObject, name) {
|
||||
|
||||
const useProperties = !name.startsWith(PREFIX);
|
||||
let extension;
|
||||
if (useProperties) {
|
||||
extension = getExtensionProperty(element, name);
|
||||
extension = getExtensionProperty(businessObject, name);
|
||||
} else {
|
||||
extension = getExtension(element, name);
|
||||
extension = getExtension(businessObject, name);
|
||||
}
|
||||
if (extension) {
|
||||
return extension.value;
|
||||
|
@ -48,20 +48,24 @@ export function getExtensionValue(element, name) {
|
|||
return '';
|
||||
}
|
||||
|
||||
export function setExtensionValue(element, name, value, moddle, commandStack) {
|
||||
export function setExtensionValue(element, name, value, moddle, commandStack, businessObject) {
|
||||
|
||||
const useProperties = !name.startsWith(PREFIX)
|
||||
const { businessObject } = element;
|
||||
|
||||
let businessObjectToUse = businessObject
|
||||
if (!businessObjectToUse) {
|
||||
businessObjectToUse = element.businessObject;
|
||||
}
|
||||
|
||||
// Assure we have extensions
|
||||
let extensions = businessObject.extensionElements;
|
||||
let extensions = businessObjectToUse.extensionElements;
|
||||
if (!extensions) {
|
||||
extensions = moddle.create('bpmn:ExtensionElements');
|
||||
}
|
||||
|
||||
if (useProperties) {
|
||||
let properties = getExtension(element, SPIFF_PARENT_PROP);
|
||||
let property = getExtensionProperty(element, name);
|
||||
let properties = getExtension(businessObjectToUse, SPIFF_PARENT_PROP);
|
||||
let property = getExtensionProperty(businessObjectToUse, name);
|
||||
if (!properties) {
|
||||
properties = moddle.create(SPIFF_PARENT_PROP);
|
||||
extensions.get('values').push(properties);
|
||||
|
@ -73,7 +77,7 @@ export function setExtensionValue(element, name, value, moddle, commandStack) {
|
|||
property.value = value;
|
||||
property.name = name;
|
||||
} else {
|
||||
let extension = getExtension(element, name);
|
||||
let extension = getExtension(businessObjectToUse, name);
|
||||
if (!extension) {
|
||||
extension = moddle.create(name);
|
||||
extensions.get('values').push(extension)
|
||||
|
@ -83,19 +87,18 @@ export function setExtensionValue(element, name, value, moddle, commandStack) {
|
|||
|
||||
commandStack.execute('element.updateModdleProperties', {
|
||||
element,
|
||||
moddleElement: businessObject,
|
||||
moddleElement: businessObjectToUse,
|
||||
properties: {
|
||||
extensionElements: extensions,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function getExtension(element, name) {
|
||||
const bizObj = element.businessObject;
|
||||
if (!bizObj.extensionElements) {
|
||||
function getExtension(businessObject, name) {
|
||||
if (!businessObject.extensionElements) {
|
||||
return null;
|
||||
}
|
||||
const extensionElements = bizObj.extensionElements.get('values');
|
||||
const extensionElements = businessObject.extensionElements.get('values');
|
||||
return extensionElements.filter(function (extensionElement) {
|
||||
if (extensionElement.$instanceOf(name)) {
|
||||
return true;
|
||||
|
@ -104,8 +107,8 @@ function getExtension(element, name) {
|
|||
}
|
||||
|
||||
|
||||
function getExtensionProperty(element, name) {
|
||||
const parentElement = getExtension(element, SPIFF_PARENT_PROP);
|
||||
function getExtensionProperty(businessObject, name) {
|
||||
const parentElement = getExtension(businessObject, SPIFF_PARENT_PROP);
|
||||
if (parentElement) {
|
||||
return parentElement.get('properties').filter(function (propertyElement) {
|
||||
return (
|
||||
|
|
|
@ -436,6 +436,7 @@ function createServiceGroup(element, translate, moddle, commandStack) {
|
|||
id: 'serviceTaskParameters',
|
||||
label: translate('Parameters'),
|
||||
component: ListGroup,
|
||||
shouldSort: false,
|
||||
...ServiceTaskParameterArray({
|
||||
element,
|
||||
moddle,
|
||||
|
|
|
@ -15,7 +15,7 @@ export function SpiffExtensionCheckboxEntry(props) {
|
|||
const debounce = useService('debounceInput');
|
||||
|
||||
const getValue = () => {
|
||||
return getExtensionValue(element, name)
|
||||
return getExtensionValue(element.businessObject, name)
|
||||
}
|
||||
|
||||
const setValue = value => {
|
||||
|
|
|
@ -14,7 +14,7 @@ export function SpiffExtensionLaunchButton(props) {
|
|||
className: 'spiffworkflow-properties-panel-button',
|
||||
id: `launch_editor_button_${name}`,
|
||||
onClick: () => {
|
||||
const value = getExtensionValue(element, name);
|
||||
const value = getExtensionValue(element.businessObject, name);
|
||||
eventBus.fire(event, {
|
||||
value,
|
||||
eventBus,
|
||||
|
|
|
@ -36,7 +36,7 @@ export function SpiffExtensionSelect(props) {
|
|||
const eventBus = useService('eventBus');
|
||||
|
||||
const getValue = () => {
|
||||
return getExtensionValue(element, name);
|
||||
return getExtensionValue(element.businessObject, name);
|
||||
};
|
||||
|
||||
const setValue = (value) => {
|
||||
|
|
|
@ -44,9 +44,7 @@ function requestServiceTaskOperators(eventBus, element, commandStack) {
|
|||
eventBus.fire('spiff.service_tasks.requested', { eventBus });
|
||||
eventBus.on('spiff.service_tasks.returned', (event) => {
|
||||
if (event.serviceTaskOperators.length > 0) {
|
||||
serviceTaskOperators = event.serviceTaskOperators.sort((a, b) =>
|
||||
a.id.localeCompare(b.id)
|
||||
);
|
||||
serviceTaskOperators = event.serviceTaskOperators;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -69,7 +67,7 @@ function getServiceTaskParameterModdleElements(shapeElement) {
|
|||
if (serviceTaskOperatorModdleElement) {
|
||||
const { parameterList } = serviceTaskOperatorModdleElement;
|
||||
if (parameterList) {
|
||||
return parameterList.parameters.sort((a, b) => a.id.localeCompare(b.id));
|
||||
return parameterList.parameters;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
|
|
|
@ -15,7 +15,7 @@ export function SpiffExtensionTextArea(props) {
|
|||
const debounce = useService('debounceInput');
|
||||
|
||||
const getValue = () => {
|
||||
return getExtensionValue(element, name)
|
||||
return getExtensionValue(element.businessObject, name)
|
||||
}
|
||||
|
||||
const setValue = value => {
|
||||
|
|
|
@ -21,17 +21,15 @@ import {
|
|||
* @returns {string|null|*}
|
||||
*/
|
||||
export function SpiffExtensionTextInput(props) {
|
||||
const element = props.element;
|
||||
const commandStack = props.commandStack, moddle = props.moddle;
|
||||
const name = props.name, label = props.label, description = props.description;
|
||||
const { element, commandStack, moddle, name, label, description, businessObject } = props;
|
||||
const debounce = useService('debounceInput');
|
||||
|
||||
const getValue = () => {
|
||||
return getExtensionValue(element, name)
|
||||
return getExtensionValue(businessObject, name)
|
||||
}
|
||||
|
||||
const setValue = value => {
|
||||
setExtensionValue(element, name, value, moddle, commandStack)
|
||||
setExtensionValue(element, name, value, moddle, commandStack, businessObject)
|
||||
};
|
||||
|
||||
return <TextFieldEntry
|
||||
|
|
|
@ -6,6 +6,9 @@ import DataObjectInterceptor from './DataObject/DataObjectInterceptor';
|
|||
import DataObjectRules from './DataObject/DataObjectRules';
|
||||
import DataObjectRenderer from './DataObject/DataObjectRenderer';
|
||||
import DataObjectPropertiesProvider from './DataObject/propertiesPanel/DataObjectPropertiesProvider';
|
||||
import DataObjectLabelEditingProvider from './DataObject/DataObjectLabelEditingProvider';
|
||||
import DataStorePropertiesProvider from './DataStoreReference/propertiesPanel/DataStorePropertiesProvider';
|
||||
import DataStoreInterceptor from './DataStoreReference/DataStoreInterceptor';
|
||||
import ConditionsPropertiesProvider from './conditions/propertiesPanel/ConditionsPropertiesProvider';
|
||||
import ExtensionsPropertiesProvider from './extensions/propertiesPanel/ExtensionsPropertiesProvider';
|
||||
import MessagesPropertiesProvider from './messages/propertiesPanel/MessagesPropertiesProvider';
|
||||
|
@ -22,6 +25,9 @@ export default {
|
|||
'dataObjectInterceptor',
|
||||
'dataObjectRules',
|
||||
'dataObjectPropertiesProvider',
|
||||
'dataObjectLabelEditingProvider',
|
||||
'dataStoreInterceptor',
|
||||
'dataStorePropertiesProvider',
|
||||
'conditionsPropertiesProvider',
|
||||
'extensionsPropertiesProvider',
|
||||
'messagesPropertiesProvider',
|
||||
|
@ -40,6 +46,9 @@ export default {
|
|||
dataObjectRules: ['type', DataObjectRules],
|
||||
dataObjectRenderer: ['type', DataObjectRenderer],
|
||||
dataObjectPropertiesProvider: ['type', DataObjectPropertiesProvider],
|
||||
dataObjectLabelEditingProvider: ['type', DataObjectLabelEditingProvider],
|
||||
dataStoreInterceptor: ['type', DataStoreInterceptor],
|
||||
dataStorePropertiesProvider: ['type', DataStorePropertiesProvider],
|
||||
conditionsPropertiesProvider: ['type', ConditionsPropertiesProvider],
|
||||
extensionsPropertiesProvider: ['type', ExtensionsPropertiesProvider],
|
||||
signalPropertiesProvider: ['type', SignalPropertiesProvider],
|
||||
|
|
|
@ -93,6 +93,17 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Category",
|
||||
"superClass": [ "Element" ],
|
||||
"properties": [
|
||||
{
|
||||
"name": "value",
|
||||
"isBody": true,
|
||||
"type": "String"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SignalButtonLabel",
|
||||
"superClass": [ "Element" ],
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
"build:watch": "webpack --watch",
|
||||
"dev": "run-p build:watch serve",
|
||||
"serve": "sirv public --dev",
|
||||
"lint": "./node_modules/.bin/eslint src *.js",
|
||||
"lint:fix": "./node_modules/.bin/eslint --fix src *.js",
|
||||
"lint": "./node_modules/.bin/eslint app *.js",
|
||||
"lint:fix": "./node_modules/.bin/eslint --fix app *.js",
|
||||
"start": "run-s build serve",
|
||||
"test": "karma start karma.conf.js"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import {
|
||||
query as domQuery,
|
||||
queryAll as domQueryAll
|
||||
} from 'min-dom';
|
||||
import {
|
||||
bootstrapPropertiesPanel,
|
||||
expectSelected,
|
||||
findGroupEntry,
|
||||
changeInput,
|
||||
PROPERTIES_PANEL_CONTAINER,
|
||||
} from './helpers';
|
||||
import conditionsPanel from '../../app/spiffworkflow/conditions';
|
||||
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
|
||||
|
||||
describe('BPMN Condition', function() {
|
||||
|
||||
let xml = require('./bpmn/conditional_event.bpmn').default;
|
||||
|
||||
beforeEach(bootstrapPropertiesPanel(xml, {
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
conditionsPanel,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
]
|
||||
}));
|
||||
|
||||
it('should add a condition panel when Conditional Event is selected', async function() {
|
||||
const shapeElement = await expectSelected('conditional_event');
|
||||
const businessObject = getBusinessObject(shapeElement);
|
||||
const conditions = findGroupEntry('conditions', PROPERTIES_PANEL_CONTAINER);
|
||||
expect(conditions).to.exist;
|
||||
|
||||
const textInput = domQuery('textarea', conditions);
|
||||
expect(textInput.value).to.equal('cancel_task_2');
|
||||
changeInput(textInput, 'True');
|
||||
});
|
||||
});
|
||||
|
|
@ -10,7 +10,7 @@ import {
|
|||
idToHumanReadableName,
|
||||
} from '../../app/spiffworkflow/DataObject/DataObjectHelpers';
|
||||
|
||||
describe('DataObject Interceptor', function() {
|
||||
describe('DataObject Interceptor', function () {
|
||||
|
||||
let xml = require('./bpmn/empty_diagram.bpmn').default;
|
||||
|
||||
|
@ -23,7 +23,7 @@ describe('DataObject Interceptor', function() {
|
|||
]
|
||||
}));
|
||||
|
||||
it('New Data Object References should create a data object if none exist.', inject(function(canvas, modeling) {
|
||||
it('New Data Object References should create a data object if none exist.', inject(function (canvas, modeling) {
|
||||
|
||||
// IF - a new dataObjectReference is created
|
||||
let rootShape = canvas.getRootElement();
|
||||
|
@ -37,7 +37,7 @@ describe('DataObject Interceptor', function() {
|
|||
|
||||
}));
|
||||
|
||||
it('New Data Object References should connect to the first available data Object if it exists', inject(function(canvas, modeling) {
|
||||
it('New Data Object References should connect to the first available data Object if it exists', inject(function (canvas, modeling) {
|
||||
|
||||
// IF - two dataObjectReferences are created
|
||||
let rootShape = canvas.getRootElement();
|
||||
|
@ -54,7 +54,7 @@ describe('DataObject Interceptor', function() {
|
|||
|
||||
}));
|
||||
|
||||
it('Deleting a data object reference does not delete the data object, unless it is the last reference', inject(function(canvas, modeling) {
|
||||
it('Deleting a data object reference does not delete the data object, unless it is the last reference', inject(function (canvas, modeling) {
|
||||
|
||||
// IF - two dataObjectReferences are created
|
||||
let rootShape = canvas.getRootElement();
|
||||
|
@ -71,7 +71,7 @@ describe('DataObject Interceptor', function() {
|
|||
expect(dataObjects.length).to.equal(1);
|
||||
}));
|
||||
|
||||
it('Deleting all the data references will also delete the data object', inject(function(canvas, modeling) {
|
||||
it('Deleting all the data references will also delete the data object', inject(function (canvas, modeling) {
|
||||
|
||||
// IF - two dataObjectReferences are created
|
||||
let rootShape = canvas.getRootElement();
|
||||
|
@ -89,7 +89,7 @@ describe('DataObject Interceptor', function() {
|
|||
expect(dataObjects.length).to.equal(0);
|
||||
}));
|
||||
|
||||
it('Creating a new Reference will update the name to match the DataObject', inject(function(canvas, modeling) {
|
||||
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();
|
||||
|
@ -101,7 +101,7 @@ describe('DataObject Interceptor', function() {
|
|||
expect(dataObjectRefShape1.businessObject.name).to.equal(human_readable_name);
|
||||
}));
|
||||
|
||||
it('should allow you to add a data object to a subprocess', inject(function(canvas, modeling, elementRegistry) {
|
||||
it('should allow you to add a data object to a subprocess', inject(function (canvas, modeling, elementRegistry) {
|
||||
|
||||
// IF - A data object reference is added to a sup-process
|
||||
let subProcessShape = elementRegistry.get('my_subprocess');
|
||||
|
@ -117,7 +117,7 @@ describe('DataObject Interceptor', function() {
|
|||
expect(dataObjects.length).to.equal(1);
|
||||
}));
|
||||
|
||||
it('Data objects in a process should be visible in a subprocess', inject(function(canvas, modeling, elementRegistry) {
|
||||
it('Data objects in a process should be visible in a subprocess', inject(function (canvas, modeling, elementRegistry) {
|
||||
|
||||
let subProcessShape = elementRegistry.get('my_subprocess');
|
||||
let subProcess = subProcessShape.businessObject;
|
||||
|
@ -132,7 +132,7 @@ describe('DataObject Interceptor', function() {
|
|||
expect(dataObjects.length).to.equal(1);
|
||||
}));
|
||||
|
||||
it('Data objects in a subprocess should not be visible in a process', inject(function(canvas, modeling, elementRegistry) {
|
||||
it('Data objects in a subprocess should not be visible in a process', inject(function (canvas, modeling, elementRegistry) {
|
||||
|
||||
let subProcessShape = elementRegistry.get('my_subprocess');
|
||||
let subProcess = subProcessShape.businessObject;
|
||||
|
@ -147,7 +147,7 @@ describe('DataObject Interceptor', function() {
|
|||
expect(dataObjects.length).to.equal(0);
|
||||
}));
|
||||
|
||||
it('References inside subprocesses should be visible in a process', inject(function(canvas, modeling, elementRegistry) {
|
||||
it('References inside subprocesses should be visible in a process', inject(function (canvas, modeling, elementRegistry) {
|
||||
|
||||
let rootShape = canvas.getRootElement();
|
||||
const refOne = modeling.createShape({ type: 'bpmn:DataObjectReference' },
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
import {
|
||||
bootstrapPropertiesPanel, changeInput,
|
||||
bootstrapPropertiesPanel,
|
||||
changeInput,
|
||||
expectSelected,
|
||||
findEntry, findInput, findSelect,
|
||||
findEntry,
|
||||
findInput,
|
||||
findSelect
|
||||
} from './helpers';
|
||||
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||
|
||||
import {
|
||||
inject,
|
||||
} from 'bpmn-js/test/helper';
|
||||
|
||||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule
|
||||
} from 'bpmn-js-properties-panel';
|
||||
|
||||
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
|
||||
import TestContainer from 'mocha-test-container-support';
|
||||
import DataObject from '../../app/spiffworkflow/DataObject';
|
||||
|
||||
describe('Properties Panel for Data Objects', function() {
|
||||
describe('Properties Panel for Data Objects', function () {
|
||||
let xml = require('./bpmn/diagram.bpmn').default;
|
||||
let container;
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
container = TestContainer.get(this);
|
||||
});
|
||||
|
||||
|
@ -29,7 +41,7 @@ describe('Properties Panel for Data Objects', function() {
|
|||
},
|
||||
}));
|
||||
|
||||
it('should allow you to see a list of data objects', async function() {
|
||||
it('should allow you to see a list of data objects', async function () {
|
||||
|
||||
// IF - a data object reference is selected
|
||||
let my_data_ref_1 = await expectSelected('my_data_ref_1');
|
||||
|
@ -45,8 +57,7 @@ describe('Properties Panel for Data Objects', function() {
|
|||
expect(selector.length).to.equal(3);
|
||||
});
|
||||
|
||||
|
||||
it('selecting a different data object should change the data model.', async function() {
|
||||
it('selecting a different data object should change the data model.', async function () {
|
||||
|
||||
// IF - a data object reference is selected
|
||||
let my_data_ref_1 = await expectSelected('my_data_ref_1');
|
||||
|
@ -62,20 +73,23 @@ describe('Properties Panel for Data Objects', function() {
|
|||
expect(businessObject.get('dataObjectRef').id).to.equal('my_third_data_object');
|
||||
});
|
||||
|
||||
it('renaming a data object, changes to the label of references', async function() {
|
||||
// Notice: Test Case for Data Object ID Changes No Longer Required
|
||||
// With our new feature implementation, changing a Data Object ID is now independent of altering
|
||||
// its Data Reference Name. This decoupling eliminates the need for the specific test case previously required for these changes.
|
||||
// it('renaming a data object, changes to the label of references', async function() {
|
||||
|
||||
// IF - a process is selected, and the name of a data object is changed.
|
||||
let entry = findEntry('ProcessTest-dataObj-2-id', container);
|
||||
let textInput = findInput('text', entry);
|
||||
changeInput(textInput, 'my_nifty_new_name');
|
||||
let my_data_ref_1 = await expectSelected('my_data_ref_1');
|
||||
// // IF - a process is selected, and the name of a data object is changed.
|
||||
// let entry = findEntry('ProcessTest-dataObj-2-id', container);
|
||||
// let textInput = findInput('text', entry);
|
||||
// changeInput(textInput, 'my_nifty_new_name');
|
||||
// let my_data_ref_1 = await expectSelected('my_data_ref_1');
|
||||
|
||||
// THEN - both the data object itself, and the label of any references are updated.
|
||||
expect(my_data_ref_1.businessObject.dataObjectRef.id).to.equal('my_nifty_new_name');
|
||||
expect(my_data_ref_1.businessObject.name).to.equal('My Nifty New Name');
|
||||
});
|
||||
// // THEN - both the data object itself, and the label of any references are updated.
|
||||
// expect(my_data_ref_1.businessObject.dataObjectRef.id).to.equal('my_nifty_new_name');
|
||||
// expect(my_data_ref_1.businessObject.name).to.equal('My Nifty New Name');
|
||||
// });
|
||||
|
||||
it('renaming a data object creates a lable without losing the numbers', async function() {
|
||||
it('renaming a data object creates a lable without losing the numbers', async function () {
|
||||
|
||||
// IF - a process is selected, and the name of a data object is changed.
|
||||
let entry = findEntry('ProcessTest-dataObj-2-id', container);
|
||||
|
@ -85,7 +99,97 @@ describe('Properties Panel for Data Objects', function() {
|
|||
|
||||
// THEN - both the data object itself, and the label of any references are updated.
|
||||
expect(my_data_ref_1.businessObject.dataObjectRef.id).to.equal('MyObject1');
|
||||
expect(my_data_ref_1.businessObject.name).to.equal('My Object 1');
|
||||
// Notice: Test Case for Data Object ID Changes No Longer Required
|
||||
// expect(my_data_ref_1.businessObject.name).to.equal('My Object 1');
|
||||
});
|
||||
|
||||
it('renaming a data object ID, does not change the label of references', async function () {
|
||||
// IF - a process is selected, and the name of a data object is changed.
|
||||
let entry = findEntry('ProcessTest-dataObj-2-id', container);
|
||||
let textInput = findInput('text', entry);
|
||||
changeInput(textInput, 'my_nifty_new_name');
|
||||
let my_data_ref_1 = await expectSelected('my_data_ref_1');
|
||||
// THEN - both the data object itself, and the label of any references are updated.
|
||||
expect(my_data_ref_1.businessObject.dataObjectRef.id).to.equal('my_nifty_new_name');
|
||||
expect(my_data_ref_1.businessObject.name).not.to.equal('My Nifty New Name');
|
||||
});
|
||||
|
||||
it('renaming a data object name, does change the label of references', async function () {
|
||||
|
||||
let entry = findEntry('ProcessTest-dataObj-2-name', container);
|
||||
let textInput = findInput('text', entry);
|
||||
let newDataObjectName = 'A New Data Object Name';
|
||||
|
||||
changeInput(textInput, newDataObjectName);
|
||||
|
||||
let my_data_ref_1 = await expectSelected('my_data_ref_1');
|
||||
let my_data_ref_2 = await expectSelected('my_data_ref_2');
|
||||
|
||||
// THEN - the label of any references are updated.
|
||||
expect(my_data_ref_1.businessObject.name).to.equal(newDataObjectName);
|
||||
expect(my_data_ref_2.businessObject.name).to.equal(newDataObjectName);
|
||||
|
||||
// Test References with DataState
|
||||
let my_data_ref_3 = await expectSelected('my_data_ref_3');
|
||||
let my_data_ref_3_DataState = my_data_ref_3.businessObject.dataState.name;
|
||||
|
||||
expect(my_data_ref_3.businessObject.name).to.equal(`${newDataObjectName} [${my_data_ref_3_DataState}]`);
|
||||
});
|
||||
|
||||
it('renaming a data object reference state, does change the label its reference', async function () {
|
||||
|
||||
let my_data_ref_1 = await expectSelected('my_data_ref_1');
|
||||
let dtObjCurrentName = my_data_ref_1.businessObject.name;
|
||||
let entry = findEntry('selectDataState-textField', container);
|
||||
let idInput = findInput('text', entry);
|
||||
let nwState = "New State";
|
||||
|
||||
// Change Data State
|
||||
changeInput(idInput, nwState);
|
||||
|
||||
// Expect new DataObjectRef Name to be like 'DataObjectRefName [DataState]'
|
||||
expect(my_data_ref_1.businessObject.name).to.equal(`${dtObjCurrentName} [${nwState}]`);
|
||||
expect(my_data_ref_1.businessObject.name).not.to.equal(dtObjCurrentName);
|
||||
});
|
||||
|
||||
it('selecting a different data object should not change the data object reference name.', async function () {
|
||||
|
||||
// IF - a data object reference is selected
|
||||
let my_data_ref_1 = await expectSelected('my_data_ref_1');
|
||||
|
||||
let entry = findEntry('selectDataObject', container);
|
||||
let selector = findSelect(entry);
|
||||
let businessObject = my_data_ref_1.businessObject;
|
||||
|
||||
changeInput(selector, 'my_third_data_object');
|
||||
|
||||
expect(businessObject.get('dataObjectRef').id).to.equal('my_third_data_object');
|
||||
expect(businessObject.name).to.equal('D3');
|
||||
expect(businessObject.name).not.to.equal('my_data_object');
|
||||
});
|
||||
|
||||
it('should not allow two dataObjects to have the same ID', inject(async function (canvas, modeling) {
|
||||
|
||||
// Creating the first dataObject
|
||||
let rootShape = canvas.getRootElement();
|
||||
const dataObject1 = modeling.createShape({ type: 'bpmn:DataObject' },
|
||||
{ x: 100, y: 100 }, rootShape);
|
||||
|
||||
// Creating the second dataObject
|
||||
const dataObject2 = modeling.createShape({ type: 'bpmn:DataObject' },
|
||||
{ x: 150, y: 100 }, rootShape);
|
||||
|
||||
await expectSelected(dataObject2.id);
|
||||
|
||||
let entry = findEntry('dataObjectId', container);
|
||||
let idInput = findInput('text', entry);
|
||||
|
||||
const duplicateId = dataObject1.businessObject.id;
|
||||
changeInput(idInput, duplicateId);
|
||||
|
||||
// Check that the ID change is not successful
|
||||
expect(dataObject2.businessObject.id).not.to.equal(duplicateId);
|
||||
|
||||
}));
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import { bootstrapPropertiesPanel, expectSelected } from './helpers';
|
||||
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||
import {
|
||||
getBpmnJS,
|
||||
inject
|
||||
} from 'bpmn-js/test/helper';
|
||||
import dataStoreInterceptor from '../../app/spiffworkflow/DataStoreReference';
|
||||
|
||||
describe('DataStore Interceptor', function () {
|
||||
|
||||
let xml = require('./bpmn/data_store.bpmn').default;
|
||||
|
||||
beforeEach(bootstrapPropertiesPanel(xml, {
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
dataStoreInterceptor,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
]
|
||||
}));
|
||||
|
||||
|
||||
it('should delete dataStore in case dataStoreRef is deleted - DataStoreReference element', inject(async function (modeling) {
|
||||
|
||||
const modeler = getBpmnJS();
|
||||
|
||||
// We Select a DataStoreReference element
|
||||
const shapeElement = await expectSelected('DataStoreReference_0eqeh4p');
|
||||
expect(shapeElement, "I can't find DataStoreReference element").to.exist;
|
||||
|
||||
let definitions = await modeler.getDefinitions();
|
||||
let dataStoreExists = definitions.get('rootElements').some(element =>
|
||||
element.$type === 'bpmn:DataStore' && element.id === 'countries'
|
||||
);
|
||||
expect(dataStoreExists, "DataStore 'countries' should be added at the root level").to.be.true;
|
||||
|
||||
// Remove dataStoreReference
|
||||
await modeler.get('modeling').removeShape(shapeElement);
|
||||
const nwshapeElement = await expectSelected('DataStoreReference_0eqeh4p');
|
||||
expect(nwshapeElement, "I can't find DataStoreReference element").not.to.exist;
|
||||
|
||||
// Check that DataStore foods is removed from the root of the process
|
||||
definitions = await modeler.getDefinitions();
|
||||
dataStoreExists = definitions.get('rootElements').some(element =>
|
||||
element.$type === 'bpmn:DataStore' && element.id === 'countries'
|
||||
);
|
||||
expect(dataStoreExists, "DataStore 'countries' should be removed from the root level").not.to.be.true;
|
||||
}));
|
||||
|
||||
});
|
|
@ -0,0 +1,158 @@
|
|||
import TestContainer from 'mocha-test-container-support';
|
||||
import {
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
} from 'bpmn-js-properties-panel';
|
||||
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import {
|
||||
bootstrapPropertiesPanel,
|
||||
changeInput,
|
||||
expectSelected,
|
||||
findGroupEntry,
|
||||
findEntry,
|
||||
findSelect,
|
||||
getPropertiesPanel
|
||||
} from './helpers';
|
||||
|
||||
import { getBpmnJS, inject } from 'bpmn-js/test/helper';
|
||||
|
||||
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
|
||||
import DataStoreReference from '../../app/spiffworkflow/DataStoreReference';
|
||||
import DataStoreInterceptor from '../../app/spiffworkflow/DataStoreReference/DataStoreInterceptor';
|
||||
|
||||
const return_datastores = (event) => {
|
||||
event.eventBus.fire('spiff.data_stores.returned', {
|
||||
options: [
|
||||
{ type: 'typeahead', name: 'countries' },
|
||||
{ type: 'kkv', name: 'foods' }
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
describe('Data Source Reference Test cases', function () {
|
||||
const xml = require('./bpmn/data_store.bpmn').default;
|
||||
let container;
|
||||
|
||||
beforeEach(function () {
|
||||
container = TestContainer.get(this);
|
||||
});
|
||||
|
||||
beforeEach(
|
||||
bootstrapPropertiesPanel(xml, {
|
||||
container,
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
DataStoreReference,
|
||||
DataStoreInterceptor,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflow: spiffModdleExtension,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
it('should display the custom data store properties group - DataStoreReference element', async function () {
|
||||
// We Select a DataStoreReference element
|
||||
const shapeElement = await expectSelected('DataStoreReference_0eqeh4p');
|
||||
expect(shapeElement, "I can't find DataStoreReference element").to.exist;
|
||||
|
||||
// Lets Check if the custom properties group is displayed
|
||||
const customGroup = findGroupEntry('custom-datastore-properties', container);
|
||||
expect(customGroup).to.exist;
|
||||
const entry = findEntry('selectDataStore', container);
|
||||
expect(entry).to.exist;
|
||||
});
|
||||
|
||||
it('should list data sources from aa api response and append it to select - DataStoreReference element', async function () {
|
||||
const modeler = getBpmnJS();
|
||||
modeler.get('eventBus').once('spiff.data_stores.requested', return_datastores);
|
||||
|
||||
// We Select a DataStoreReference element
|
||||
const shapeElement = await expectSelected('DataStoreReference_0eqeh4p');
|
||||
expect(shapeElement, "I can't find DataStoreReference element").to.exist;
|
||||
|
||||
// Interact with the DataStoreSelect component
|
||||
const selectGroup = findGroupEntry('custom-datastore-properties', container)
|
||||
expect(selectGroup).to.exist;
|
||||
|
||||
const entry = findEntry('selectDataStore', getPropertiesPanel());
|
||||
expect(entry).to.exist;
|
||||
|
||||
// Verification if the dataStoreRef attribute is updated
|
||||
let selector = findSelect(entry);
|
||||
expect(selector.length).to.equal(3);
|
||||
expect(selector[1].value === 'countries');
|
||||
expect(selector[2].value === 'foods');
|
||||
});
|
||||
|
||||
it('should update dataStoreRef after a select event && should add new DataState in the level of process definition - DataStoreReference element', async function () {
|
||||
const modeler = getBpmnJS();
|
||||
modeler.get('eventBus').once('spiff.data_stores.requested', return_datastores);
|
||||
|
||||
// We Select a DataStoreReference element
|
||||
const shapeElement = await expectSelected('DataStoreReference_0eqeh4p');
|
||||
expect(shapeElement, "I can't find DataStoreReference element").to.exist;
|
||||
|
||||
// Interact with the DataStoreSelect component
|
||||
const selectGroup = findGroupEntry('custom-datastore-properties', container)
|
||||
expect(selectGroup).to.exist;
|
||||
|
||||
const entry = findEntry('selectDataStore', getPropertiesPanel());
|
||||
expect(entry).to.exist;
|
||||
|
||||
// Verification if the dataStoreRef attribute is updated
|
||||
let selector = findSelect(entry);
|
||||
changeInput(selector, 'foods');
|
||||
const nwbusinessObject = getBusinessObject(shapeElement);
|
||||
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('foods');
|
||||
|
||||
// Check if the DataStore is added at the root level
|
||||
const definitions = modeler.getDefinitions();
|
||||
const dataStoreExists = definitions.get('rootElements').some(element =>
|
||||
element.$type === 'bpmn:DataStore' && element.id === 'foods'
|
||||
);
|
||||
expect(dataStoreExists, "DataStore 'foods' should be added at the root level").to.be.true;
|
||||
|
||||
});
|
||||
|
||||
it('should delete dataStore if dataStorRef is updated - DataStoreReference element', async function () {
|
||||
const modeler = getBpmnJS();
|
||||
modeler.get('eventBus').once('spiff.data_stores.requested', return_datastores);
|
||||
|
||||
// We Select a DataStoreReference element
|
||||
const shapeElement = await expectSelected('DataStoreReference_0eqeh4p');
|
||||
expect(shapeElement, "I can't find DataStoreReference element").to.exist;
|
||||
|
||||
// Interact with the DataStoreSelect component
|
||||
const selectGroup = findGroupEntry('custom-datastore-properties', container)
|
||||
expect(selectGroup).to.exist;
|
||||
|
||||
const entry = findEntry('selectDataStore', getPropertiesPanel());
|
||||
expect(entry).to.exist;
|
||||
|
||||
// Verification if the dataStoreRef attribute is updated
|
||||
let selector = findSelect(entry);
|
||||
changeInput(selector, 'foods');
|
||||
let nwbusinessObject = getBusinessObject(shapeElement);
|
||||
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('foods');
|
||||
// Then choose new dataStore
|
||||
changeInput(selector, 'countries');
|
||||
nwbusinessObject = getBusinessObject(shapeElement);
|
||||
expect(nwbusinessObject.get('dataStoreRef').id).to.equal('countries');
|
||||
|
||||
// Check if the DataStore is added at the root level with the updated dataStore
|
||||
const definitions = modeler.getDefinitions();
|
||||
const countriesDataStoreExists = definitions.get('rootElements').some(element =>
|
||||
element.$type === 'bpmn:DataStore' && element.id === 'countries'
|
||||
);
|
||||
expect(countriesDataStoreExists, "DataStore 'countries' should be added at the root level").to.be.true;
|
||||
const foodsDataStoreExists = definitions.get('rootElements').some(element =>
|
||||
element.$type === 'bpmn:DataStore' && element.id === 'foods'
|
||||
);
|
||||
expect(foodsDataStoreExists, "DataStore 'countries' should be removed from the root level").not.to.be.true;
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -131,8 +131,8 @@ describe('Properties Panel for User Tasks', function () {
|
|||
eventBus.fire('spiff.jsonSchema.update', {
|
||||
value: 'new-schema.json',
|
||||
});
|
||||
const jsonFile = getExtensionValue(userElement, 'formJsonSchemaFilename');
|
||||
const uiFile = getExtensionValue(userElement, 'formUiSchemaFilename');
|
||||
const jsonFile = getExtensionValue(userElement.businessObject, 'formJsonSchemaFilename');
|
||||
const uiFile = getExtensionValue(userElement.businessObject, 'formUiSchemaFilename');
|
||||
expect(jsonFile).to.equal('new-schema.json');
|
||||
expect(uiFile).to.equal('new-uischema.json');
|
||||
|
||||
|
@ -155,7 +155,7 @@ describe('Properties Panel for User Tasks', function () {
|
|||
const businessObject = getBusinessObject(userElement);
|
||||
// The change is reflected in the business object
|
||||
let instructions = getExtensionValue(
|
||||
userElement,
|
||||
businessObject,
|
||||
'spiffworkflow:InstructionsForEndUser'
|
||||
);
|
||||
expect(instructions).to.equal('#Hello!');
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
<?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: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="main" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0n934tk</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0n934tk" sourceRef="StartEvent_1" targetRef="setup" />
|
||||
<bpmn:parallelGateway id="gateway_1">
|
||||
<bpmn:incoming>Flow_0ghdmcg</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1kyhah1</bpmn:outgoing>
|
||||
<bpmn:outgoing>Flow_1texcs9</bpmn:outgoing>
|
||||
</bpmn:parallelGateway>
|
||||
<bpmn:task id="task_1" name="Task 1">
|
||||
<bpmn:incoming>Flow_1kyhah1</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_16kfh39</bpmn:outgoing>
|
||||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="Flow_1kyhah1" sourceRef="gateway_1" targetRef="task_1" />
|
||||
<bpmn:sequenceFlow id="Flow_16kfh39" sourceRef="task_1" targetRef="gateway_2" />
|
||||
<bpmn:parallelGateway id="gateway_2">
|
||||
<bpmn:incoming>Flow_16kfh39</bpmn:incoming>
|
||||
<bpmn:incoming>Flow_1u8w68b</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1wczxjh</bpmn:outgoing>
|
||||
</bpmn:parallelGateway>
|
||||
<bpmn:endEvent id="normal_end">
|
||||
<bpmn:incoming>Flow_1wczxjh</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1wczxjh" sourceRef="gateway_2" targetRef="normal_end" />
|
||||
<bpmn:boundaryEvent id="conditional_event" attachedToRef="task_2">
|
||||
<bpmn:outgoing>Flow_1ybk8c2</bpmn:outgoing>
|
||||
<bpmn:conditionalEventDefinition id="ConditionalEventDefinition_0q26i1s">
|
||||
<bpmn:condition>cancel_task_2</bpmn:condition>
|
||||
</bpmn:conditionalEventDefinition>
|
||||
</bpmn:boundaryEvent>
|
||||
<bpmn:endEvent id="conditional_end">
|
||||
<bpmn:incoming>Flow_1ybk8c2</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1ybk8c2" sourceRef="conditional_event" targetRef="conditional_end" />
|
||||
<bpmn:task id="task_2" name="Task 2">
|
||||
<bpmn:incoming>Flow_1texcs9</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1u8w68b</bpmn:outgoing>
|
||||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="Flow_1texcs9" sourceRef="gateway_1" targetRef="task_2" />
|
||||
<bpmn:sequenceFlow id="Flow_1u8w68b" sourceRef="task_2" targetRef="gateway_2" />
|
||||
<bpmn:task id="setup" name="Setup">
|
||||
<bpmn:incoming>Flow_0n934tk</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0ghdmcg</bpmn:outgoing>
|
||||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="Flow_0ghdmcg" sourceRef="setup" targetRef="gateway_1" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_16xfaqc">
|
||||
<bpmndi:BPMNShape id="Gateway_1k9pqw1_di" bpmnElement="gateway_1">
|
||||
<dc:Bounds x="425" y="165" width="50" height="50" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0ilxk3l_di" bpmnElement="task_1">
|
||||
<dc:Bounds x="530" y="150" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Gateway_1a3gl8a_di" bpmnElement="gateway_2">
|
||||
<dc:Bounds x="685" y="165" width="50" height="50" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1y4buya_di" bpmnElement="normal_end">
|
||||
<dc:Bounds x="792" y="172" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0f7n8iv_di" bpmnElement="task_2">
|
||||
<dc:Bounds x="530" y="280" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1gkguhe_di" bpmnElement="conditional_end">
|
||||
<dc:Bounds x="652" y="402" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_1v7pfua_di" bpmnElement="setup">
|
||||
<dc:Bounds x="280" y="150" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1vhin9h_di" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="192" y="172" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1vn14hl_di" bpmnElement="conditional_event">
|
||||
<dc:Bounds x="562" y="342" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_0n934tk_di" bpmnElement="Flow_0n934tk">
|
||||
<di:waypoint x="228" y="190" />
|
||||
<di:waypoint x="280" y="190" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1kyhah1_di" bpmnElement="Flow_1kyhah1">
|
||||
<di:waypoint x="475" y="190" />
|
||||
<di:waypoint x="530" y="190" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_16kfh39_di" bpmnElement="Flow_16kfh39">
|
||||
<di:waypoint x="630" y="190" />
|
||||
<di:waypoint x="685" y="190" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1wczxjh_di" bpmnElement="Flow_1wczxjh">
|
||||
<di:waypoint x="735" y="190" />
|
||||
<di:waypoint x="792" y="190" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1ybk8c2_di" bpmnElement="Flow_1ybk8c2">
|
||||
<di:waypoint x="580" y="378" />
|
||||
<di:waypoint x="580" y="420" />
|
||||
<di:waypoint x="652" y="420" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1texcs9_di" bpmnElement="Flow_1texcs9">
|
||||
<di:waypoint x="450" y="215" />
|
||||
<di:waypoint x="450" y="320" />
|
||||
<di:waypoint x="530" y="320" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1u8w68b_di" bpmnElement="Flow_1u8w68b">
|
||||
<di:waypoint x="630" y="320" />
|
||||
<di:waypoint x="710" y="320" />
|
||||
<di:waypoint x="710" y="215" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_0ghdmcg_di" bpmnElement="Flow_0ghdmcg">
|
||||
<di:waypoint x="380" y="190" />
|
||||
<di:waypoint x="425" y="190" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -0,0 +1,63 @@
|
|||
<?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_1udyjxo</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0vt1twq" sourceRef="StartEvent_1" targetRef="my_user_task" />
|
||||
<bpmn:sequenceFlow id="Flow_1udyjxo" sourceRef="my_user_task" targetRef="Event_0yxpeto" />
|
||||
<bpmn:userTask id="my_user_task" name="Complete Web Form">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField type="boolean">
|
||||
<camunda:properties>
|
||||
<camunda:property />
|
||||
</camunda:properties>
|
||||
<camunda:validation>
|
||||
<camunda:constraint />
|
||||
</camunda:validation>
|
||||
</camunda:formField>
|
||||
</camunda:formData>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_0vt1twq</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1udyjxo</bpmn:outgoing>
|
||||
<bpmn:dataOutputAssociation id="DataOutputAssociation_1nwrgyb">
|
||||
<bpmn:targetRef>DataStoreReference_0eqeh4p</bpmn:targetRef>
|
||||
</bpmn:dataOutputAssociation>
|
||||
</bpmn:userTask>
|
||||
<bpmn:dataStoreReference id="DataStoreReference_0eqeh4p" dataStoreRef="countries" />
|
||||
</bpmn:process>
|
||||
<bpmn:dataStore id="countries" name="DataStore_countries" />
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_16xfaqc">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="142" y="82" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_0yxpeto_di" bpmnElement="Event_0yxpeto">
|
||||
<dc:Bounds x="422" y="82" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0096bsk_di" bpmnElement="my_user_task">
|
||||
<dc:Bounds x="260" y="60" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="DataStoreReference_0eqeh4p_di" bpmnElement="DataStoreReference_0eqeh4p">
|
||||
<dc:Bounds x="345" y="265" width="50" height="50" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_0vt1twq_di" bpmnElement="Flow_0vt1twq">
|
||||
<di:waypoint x="178" y="100" />
|
||||
<di:waypoint x="260" y="100" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1udyjxo_di" bpmnElement="Flow_1udyjxo">
|
||||
<di:waypoint x="360" y="100" />
|
||||
<di:waypoint x="422" y="100" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="DataOutputAssociation_1nwrgyb_di" bpmnElement="DataOutputAssociation_1nwrgyb">
|
||||
<di:waypoint x="323" y="140" />
|
||||
<di:waypoint x="364" y="265" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -38,7 +38,7 @@
|
|||
<bpmn:script>elizabeth="awesome"</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:dataObject id="my_other_data_object" />
|
||||
<bpmn:dataObject id="my_third_data_object" />
|
||||
<bpmn:dataObject id="my_third_data_object" name="D3" />
|
||||
<bpmn:dataObjectReference id="my_data_ref_1" name="my_data_object" dataObjectRef="my_data_object" />
|
||||
<bpmn:sequenceFlow id="Flow_132laxn" sourceRef="task_confirm" targetRef="business_rule_task" />
|
||||
<bpmn:userTask id="task_confirm" name="confirm contentment">
|
||||
|
@ -61,6 +61,11 @@
|
|||
</camunda:properties>
|
||||
</bpmn:extensionElements>
|
||||
</bpmn:dataObjectReference>
|
||||
|
||||
<bpmn:dataObjectReference id="my_data_ref_3" name="my_data_object" dataObjectRef="my_data_object">
|
||||
<bpmn:dataState id="DataState_my_data_ref_3" name="OK" />
|
||||
</bpmn:dataObjectReference>
|
||||
|
||||
<bpmn:dataObject id="my_data_object" />
|
||||
<bpmn:sequenceFlow id="Flow_1lu1qyz" sourceRef="business_rule_task" targetRef="Event_14wzv4j" />
|
||||
<bpmn:businessRuleTask id="business_rule_task">
|
||||
|
@ -119,6 +124,12 @@
|
|||
<dc:Bounds x="451" y="322" width="78" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="DataObjectReference_08bm73g_di" bpmnElement="my_data_ref_3">
|
||||
<dc:Bounds x="472" y="265" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="451" y="322" width="78" height="14" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="dataInput_1" bpmnElement="num_dogs">
|
||||
<dc:Bounds x="172" y="85" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
|
|
Loading…
Reference in New Issue