fixes to the Data Object model - some serious cleanup of names so things make a little more sense.

This commit is contained in:
Dan 2022-07-05 13:44:02 -04:00
parent 4c413c4907
commit 13a00d1762
8 changed files with 256 additions and 155 deletions

View File

@ -1,6 +1,6 @@
import scriptProps, { SCRIPT_TYPE } from './parts/ScriptProps';
import scriptGroup, { SCRIPT_TYPE } from './parts/ScriptGroup';
import { is, isAny } from 'bpmn-js/lib/util/ModelUtil';
import dataObjectProps from './parts/DataReferenceProps';
import dataReferenceGroup from './parts/DataReferenceGroup';
const LOW_PRIORITY = 500;
@ -35,7 +35,7 @@ function createScriptGroup(element, translate, moddle) {
return {
id: 'spiff_script',
label: translate('SpiffWorkflow Properties'),
entries: scriptProps(element, moddle, SCRIPT_TYPE.bpmn, 'Script', 'Code to execute.')
entries: scriptGroup(element, moddle, SCRIPT_TYPE.bpmn, 'Script', 'Code to execute.')
};
}
@ -52,12 +52,12 @@ function preScriptPostScriptGroup(element, translate, moddle) {
id: 'spiff_pre_post_scripts',
label: translate('Pre-Script and Post-Script'),
entries: [
...scriptProps(element,
...scriptGroup(element,
moddle,
SCRIPT_TYPE.pre,
'Pre-Script',
'Code to execute prior to this task.'),
...scriptProps(element,
...scriptGroup(element,
moddle,
SCRIPT_TYPE.post,
'Post-Script',
@ -66,10 +66,18 @@ function preScriptPostScriptGroup(element, translate, moddle) {
};
}
/**
* Create a group on the main panel with a select box (for choosing the Data Object to connect) AND a
* full Data Object Array for modifying all the data objects.
* @param element
* @param translate
* @param moddle
* @returns entries
*/
function createDataObjectGroup(element, translate, moddle) {
return {
id: 'data_object_properties',
label: translate('Data Object Properties'),
entries: dataObjectProps(element, moddle)
entries: dataReferenceGroup(element, moddle)
};
}

View File

@ -0,0 +1,110 @@
import { useService } from 'bpmn-js-properties-panel';
import { getBusinessObject, is } from 'bpmn-js/lib/util/ModelUtil';
import { isTextFieldEntryEdited, TextFieldEntry } from '@bpmn-io/properties-panel';
/**
* Provides a list of data objects, and allows you to add / remove data objects, and change their ids.
* @param props
* @constructor
*/
export function DataObjectArray(props) {
const moddle = props.moddle;
const element = props.dataElement;
const process = getProcess(element);
let dataObjects = [];
for (const element of process.flowElements) {
if (element.$type === 'bpmn:DataObject') {
dataObjects.push(element);
}
}
const items = dataObjects.map((dataObject, index) => {
const id = element.id + '-dataObjects-' + index;
return {
id: id,
label: dataObject.id,
entries: [
DataObjectGroup({
idPrefix: id,
element,
dataObject
})
],
autoFocusEntry: dataObject.id,
remove: remove
};
});
function add(event) {
// event.stopPropagation();
console.log('PLEASE ADD A NEW DATA OBJECT');
}
function remove(event) {
// event.stopPropagation();
console.log('PLEASE REMOVE A DATA OBJECT');
}
console.log("About to return the following items:", items);
return { items, add };
}
function DataObjectGroup(props) {
const {
idPrefix,
element,
dataObject
} = props;
let entries =
{
id: idPrefix + '-dataObject',
component: DataObjectTextField,
isEdited: isTextFieldEntryEdited,
idPrefix,
dataObject
};
console.log("Data Object Group", entries);
return entries;
}
function DataObjectTextField(props) {
console.log("The Text Field is Being Created");
const {
idPrefix,
element,
parameter
} = props;
const commandStack = useService('commandStack');
const translate = useService('translate');
const debounce = useService('debounceInput');
const setValue = (value) => {
console.log('set data object value ');
};
const getValue = (parameter) => {
console.log('get data object value ');
};
return TextFieldEntry({
element: parameter,
id: idPrefix + '-name',
label: 'Data Object Name',
getValue,
setValue,
debounce
});
}
function getProcess(element) {
let parent = element.parent;
return is(parent, 'bpmn:Process') ?
getBusinessObject(parent) :
getBusinessObject(parent).get('processRef');
}

View File

@ -0,0 +1,67 @@
import {useService } from 'bpmn-js-properties-panel';
import { SelectEntry } from '@bpmn-io/properties-panel';
/**
* Finds the value of the given type within the extensionElements
* given a type of "spiff:preScript", would find it in this, and retnr
* the object.
*
* <bpmn:
<bpmn:userTask id="123" name="My User Task!">
<bpmn:extensionElements>
<spiff:preScript>
me = "100% awesome"
</spiff:preScript>
</bpmn:extensionElements>
...
</bpmn:userTask>
*
* @returns {string|null|*}
*/
export function DataObjectSelect(props) {
const moddle = props.moddle;
const id = props.id;
const element = props.element;
const debounce = useService('debounceInput');
const getValue = () => {
return element.businessObject.dataObjectRef.id
}
const setValue = value => {
const businessObject = element.businessObject;
for (const element of businessObject.$parent.flowElements) {
if (element.$type === 'bpmn:DataObject' && element.id === value) {
businessObject.dataObjectRef = element;
}
}
}
const getOptions = value => {
console.log("Hey there (options)!")
const businessObject = element.businessObject;
const parent = businessObject.$parent;
let options = []
for (const element of parent.flowElements) {
if (element.$type === 'bpmn:DataObject') {
options.push({label: element.id, value: element.id})
}
}
return options
}
const select = <SelectEntry
id={'selectDataObject'}
element={element}
description={"Select the Data Object this represents."}
label={"Which Data Object does this reference?"}
getValue={ getValue }
setValue={ setValue }
getOptions={ getOptions }
debounce={debounce}
/>;
console.log("Returning this:", select)
return select
}

View File

@ -0,0 +1,44 @@
import { ListGroup, isTextFieldEntryEdited } from '@bpmn-io/properties-panel';
import { DataObjectSelect } from './DataObjectSelect';
import { DataObjectArray } from './DataObjectArray';
/**
* Allows you to associate the selected Data Reference to a
* data object. Many references can point to the same data object.
* Also allows you to select which Data Objects are available
* in the system overall.
* @param dataElement The selected Data Object Reference
* @param moddle For updating the underlying xml object
* @returns {[{component: (function(*)), isEdited: *, id: string, element},{component:
* (function(*)), isEdited: *, id: string, element}]}
*/
export default function(dataElement, moddle) {
const groupSections = [];
groupSections.push({
id: 'selectDataObject',
dataElement,
component: DataObjectSelect,
isEdited: isTextFieldEntryEdited,
moddle: moddle,
});
const dataObjectArray = {
id: 'editDataObjects',
dataElement,
label: 'Available Data Objects',
component: ListGroup,
...DataObjectArray({ dataElement, moddle })
};
console.log('The Data Objects Array is ', dataObjectArray);
if (dataObjectArray.items) {
groupSections.push(dataObjectArray);
}
return groupSections;
}

View File

@ -1,148 +0,0 @@
import { Group, ListGroup, SelectEntry, isTextFieldEntryEdited, TextEntry } from '@bpmn-io/properties-panel';
import {useService} from 'bpmn-js-properties-panel';
import {getBusinessObject} from 'bpmn-js/lib/util/ModelUtil';
import {remove as collectionRemove} from 'diagram-js/lib/util/Collections';
/**
* Allows you to associate the selected Data Reference to a
* data object. Many references can point to the same data object.
* Also allows you to select which Data Objects are available
* in the system overall.
* @param dataElement The selected Data Object Reference
* @param moddle For updating the underlying xml object
* @returns {[{component: (function(*)), isEdited: *, id: string, element},{component: (function(*)), isEdited: *, id: string, element}]}
*/
export default function (dataElement, moddle) {
return [
{
id: 'selectDataObject',
dataElement,
component: DataObjectSelector,
isEdited: isTextFieldEntryEdited,
moddle: moddle,
},
{
id: 'editDataObjects',
dataElement,
label: 'Available Data Objects',
component: Group,
entries: [
...DataObjectProps({dataElement, moddle})
]
}
];
}
/**
* Finds the value of the given type within the extensionElements
* given a type of "spiff:preScript", would find it in this, and retnr
* the object.
*
* <bpmn:
<bpmn:userTask id="123" name="My User Task!">
<bpmn:extensionElements>
<spiff:preScript>
me = "100% awesome"
</spiff:preScript>
</bpmn:extensionElements>
...
</bpmn:userTask>
*
* @returns {string|null|*}
*/
function DataObjectSelector(props) {
const moddle = props.moddle;
const id = props.id;
const element = props.element;
const debounce = useService('debounceInput');
const getValue = () => {
return element.businessObject.dataObjectRef.id
}
const setValue = value => {
const businessObject = element.businessObject;
for (const element of businessObject.$parent.flowElements) {
if (element.$type === 'bpmn:DataObject' && element.id === value) {
businessObject.dataObjectRef = element;
}
}
}
const getOptions = value => {
const businessObject = element.businessObject;
const parent = businessObject.$parent;
let options = []
for (const element of parent.flowElements) {
if (element.$type === 'bpmn:DataObject') {
options.push({label: element.id, value: element.id})
}
}
return options
}
return <SelectEntry
id={'selectDataObject'}
element={element}
description={"Select the Data Object this represents."}
label={"Which Data Object does this reference?"}
getValue={ getValue }
setValue={ setValue }
getOptions={ getOptions }
debounce={debounce}
/>;
}
/**
* Provides a list of data objects, and allows you to add / remove data objects, and change their ids.
* @param props
* @constructor
*/
function DataObjectProps(props) {
const moddle = props.moddle;
const id = props.id;
const element = props.dataElement;
const businessObject = element.businessObject;
const parent = businessObject.$parent;
let dataObjects = []
for (const element of parent.flowElements) {
if (element.$type === 'bpmn:DataObject') {
dataObjects.push(element)
}
}
const entries = dataObjects.map((dataObject, index) => {
return {
id: dataObject.id,
label: dataObject.id,
autoFocusEntry: dataObject.id,
remove: removeDataObject({ dataObject })
};
});
return entries
function removeDataObject({ dataObject }) {
return function(event) {
const parent = dataObject.$parent
collectionRemove(parent, dataObject);
};
}
function addFactory({ bpmnFactory, commandStack, element }) {
return function(event) {
event.stopPropagation();
const businessObject = element.businessObject.$parent;
businessObject.add('bpmn:DataObject')
};
}
}

View File

@ -1,7 +1,7 @@
import {
bootstrapPropertiesPanel, changeInput,
expectSelected,
findEntry, findSelect,
findEntry, findGroupEntry, findSelect,
} from './helpers';
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
import SpiffWorkflowPropertiesProvider from '../../app/spiffworkflow/PropertiesPanel';
@ -46,6 +46,22 @@ describe('Properties Panel Script Tasks', function() {
expect(selector.length).to.equal(3);
});
it('should allow you to edit the data objects', async function() {
// IF - a data object reference is selected
let my_data_ref_1 = await expectSelected('my_data_ref_1');
// THEN - an edit Data Objects group section should appear in the properties panel
let entry = findGroupEntry('editDataObjects', container);
expect(entry).to.exist;
// And it should contain three items in the group.
});
it('selecting a data object should change the data model.', async function() {
// IF - a data object reference is selected

View File

@ -97,6 +97,10 @@ export function findEntry(id, container) {
return domQuery(`[data-entry-id='${ id }']`, container);
}
export function findGroupEntry(id, container) {
return domQuery(`[data-group-id='group-${ id }']`, container);
}
export function findInput(type, container) {
return domQuery(`input[type='${ type }']`, container);
}