Added ability to select which data object is associated with a data object reference.

This commit is contained in:
Dan 2022-07-01 13:01:52 -04:00
parent 212bd0c1ac
commit 2527bf2823
9 changed files with 122 additions and 65 deletions

View File

@ -1,4 +1,4 @@
import {HeaderButton, TextAreaEntry, TextFieldEntry, isTextFieldEntryEdited} from '@bpmn-io/properties-panel';
import { SelectEntry, isTextFieldEntryEdited} from '@bpmn-io/properties-panel';
import {useService} from 'bpmn-js-properties-panel';
/**
@ -43,33 +43,39 @@ function DataObjectSelector(props) {
const element = props.element;
const debounce = useService('debounceInput');
/**
* Returns a list of all the data business objects.
* @returns {string|null|*}
*/
const findDataObjects = () => {
// Find the parent process of this business object.
const businessObject = element.businessObject;
const parent = businessObject.parent
};
const getValue = () => {
return ""
return element.businessObject.dataObjectRef.id
}
const setValue = value => {
return ""
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 <TextAreaEntry
id={id}
return <SelectEntry
id={'selectDataObject'}
element={element}
description={"My Text Area"}
label={"Help me!"}
description={"Select the Data Object this represents."}
label={"Which Data Object does this reference?"}
getValue={ getValue }
setValue={ setValue }
getOptions={ getOptions }
debounce={debounce}
/>;
}

View File

@ -8,8 +8,6 @@ const {
} = require('webpack');
const basePath = '.';
const absoluteBasePath = path.resolve(path.join(__dirname, basePath));
const singleStart = process.env.SINGLE_START;
module.exports = function(karma) {
karma.set({
@ -30,7 +28,7 @@ module.exports = function(karma) {
'test/spec/**/*Spec.js': [ 'webpack', 'env' ]
},
browsers: [ 'Chrome' ],
browsers: [ 'ChromeHeadless' ],
browserNoActivityTimeout: 30000,

1
package-lock.json generated
View File

@ -14,6 +14,7 @@
"diagram-js": "^8.5.0",
"inherits": "^2.0.4",
"min-dash": "^3.8.1",
"min-dom": "^3.2.1",
"moddle": "^5.0.3"
},
"devDependencies": {

View File

@ -69,6 +69,7 @@
"diagram-js": "^8.5.0",
"inherits": "^2.0.4",
"min-dash": "^3.8.1",
"min-dom": "^3.2.1",
"moddle": "^5.0.3"
}
}

View File

@ -9,7 +9,7 @@
<bpmn:outgoing>Flow_1mezzcx</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:endEvent id="Event_14wzv4j">
<bpmn:incoming>Flow_0q4oys2</bpmn:incoming>
<bpmn:incoming>Flow_0q4oys2</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_01jg677" sourceRef="Activity_15zz6ya" targetRef="my_script_task" />
<bpmn:sequenceFlow id="Flow_1mezzcx" sourceRef="StartEvent_1" targetRef="Activity_15zz6ya" />
@ -31,10 +31,11 @@
<bpmn:targetRef>Property_1w1963p</bpmn:targetRef>
</bpmn:dataInputAssociation>
</bpmn:scriptTask>
<bpmn:dataObjectReference id="my_data_ref_1" name="Data 1" dataObjectRef="DataObject_13tnlgu" />
<bpmn:dataObject id="DataObject_13tnlgu" />
<bpmn:dataObjectReference id="my_data_ref_2" name="Data 2" dataObjectRef="DataObject_0n982mk" />
<bpmn:dataObject id="DataObject_0n982mk" />
<bpmn:dataObject id="my_data_object" />
<bpmn:dataObject id="my_other_data_object" />
<bpmn:dataObject id="my_third_data_object" />
<bpmn:dataObjectReference id="my_data_ref_1" name="my_data_object" dataObjectRef="my_data_object" />
<bpmn:dataObjectReference id="my_data_ref_2" name="my_data_object" dataObjectRef="my_data_object" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1mzevep">
@ -97,4 +98,4 @@
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
</bpmn:definitions>

View File

@ -1,19 +1,24 @@
import {
bootstrapPropertiesPanel,
bootstrapPropertiesPanel, changeInput,
expectSelected,
findEntry,
PROPERTIES_PANEL_CONTAINER
findEntry, findSelect,
} from './helpers';
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
import SpiffWorkflowPropertiesProvider from '../../app/spiffworkflow/PropertiesPanel';
import inputOutput from '../../app/spiffworkflow/InputOutput';
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
import TestContainer from 'mocha-test-container-support';
describe('Properties Panel Script Tasks', function() {
let xml = require('./diagram.bpmn').default;
let container;
beforeEach(function() {
container = TestContainer.get(this);
});
beforeEach(bootstrapPropertiesPanel(xml, {
container,
debounceInput: false,
additionalModules: [
SpiffWorkflowPropertiesProvider,
@ -25,24 +30,37 @@ describe('Properties Panel Script Tasks', function() {
},
}));
it('should allow you to see a list of data objects', async function() {
it('should allow you to see all data objects', async function() {
// 1. Select the data object reference 'my_data_ref_1'
// IF - a data object reference is selected
let my_data_ref_1 = await expectSelected('my_data_ref_1');
expect(my_data_ref_1).to.exist;
// 2. The props panel should include a dataObjects section.
let entry = findEntry('dataObjects', PROPERTIES_PANEL_CONTAINER);
// THEN - a select Data Object section should appear in the properties panel
let entry = findEntry('selectDataObject', container);
expect(entry).to.exist;
// 3. There should be two data objects in the BPMN/Moddle
// 3. The entry List should contain a select box that contains all
// of the data elements.
// AND - That that properties' pane selection should contain a dropdown with a value in it.
let selector = findSelect(entry);
expect(selector).to.exist;
expect(selector.length).to.equal(3);
});
it('selecting a 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');
let entry = findEntry('selectDataObject', container);
let selector = findSelect(entry);
let businessObject = my_data_ref_1.businessObject;
// AND we select a dataObjectReference (we know it has this value, because we created the bpmn file)
changeInput(selector, 'my_third_data_object');
// then this data reference object now references that data object.
expect(businessObject.get('dataObjectRef').id).to.equal('my_third_data_object');
});
});

View File

@ -1,13 +1,17 @@
import {
bootstrapPropertiesPanel,
bootstrapPropertiesPanel, changeInput,
expectSelected,
findEntry,
PROPERTIES_PANEL_CONTAINER
} from './helpers';
import {
query as domQuery,
} from 'min-dom';
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
import inputOutput from '../../app/spiffworkflow/InputOutput';
import SpiffWorkflowPropertiesProvider from '../../app/spiffworkflow/PropertiesPanel';
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
describe('Properties Panel Script Tasks', function() {
let xml = require('./diagram.bpmn').default;
@ -24,15 +28,29 @@ describe('Properties Panel Script Tasks', function() {
},
}));
it('should allow you to add a script to a script task', async function() {
// 1. Select the script task 'my_script_task'
it('should display a script editing panel when a script task is selected', async function() {
// IF - you select a script task
expectSelected('my_script_task');
// 2. Assure properties panel has a pythonScript
// THEN - a properties panel exists with a section for editing that script
let entry = findEntry('pythonScript_bpmn:script', PROPERTIES_PANEL_CONTAINER);
expect(entry).to.exist;
// 3. Assere there is a text input called 'script'
// 4. Adding text to that script input updates the script in the bpmn.
const scriptInput = domQuery('textarea', entry);
expect(scriptInput).to.exist;
});
it('should update the bpmn:script tag when you modify the script field', async function() {
// IF - a script tag is selected, and you change the script in the properties panel
const scriptTask = await expectSelected('my_script_task');
let entry = findEntry('pythonScript_bpmn:script', PROPERTIES_PANEL_CONTAINER);
const scriptInput = domQuery('textarea', entry);
changeInput(scriptInput, 'x = 1');
// THEN - the script tag in the BPMN Business object / XML is updated as well.
let businessObject = getBusinessObject(scriptTask);
expect(businessObject.get('script')).to.equal('x = 1');
});
});

View File

@ -31,10 +31,11 @@
<bpmn:targetRef>Property_1w1963p</bpmn:targetRef>
</bpmn:dataInputAssociation>
</bpmn:scriptTask>
<bpmn:dataObjectReference id="my_data_ref_1" name="Data 1" dataObjectRef="DataObject_13tnlgu" />
<bpmn:dataObject id="DataObject_13tnlgu" />
<bpmn:dataObjectReference id="my_data_ref_2" name="Data 2" dataObjectRef="DataObject_0n982mk" />
<bpmn:dataObject id="DataObject_0n982mk" />
<bpmn:dataObject id="my_data_object" />
<bpmn:dataObject id="my_other_data_object" />
<bpmn:dataObject id="my_third_data_object" />
<bpmn:dataObjectReference id="my_data_ref_1" name="my_data_object" dataObjectRef="my_data_object" />
<bpmn:dataObjectReference id="my_data_ref_2" name="my_data_object" dataObjectRef="my_data_object" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1mzevep">
@ -97,4 +98,4 @@
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
</bpmn:definitions>

View File

@ -1,7 +1,7 @@
import {
query as domQuery,
} from 'min-dom';
import { act } from '@testing-library/preact';
import { act, fireEvent } from '@testing-library/preact';
import {
getBpmnJS,
@ -9,18 +9,17 @@ import {
import Modeler from 'bpmn-js/lib/Modeler';
import TestContainer from 'mocha-test-container-support';
import { bootstrapBpmnJS, inject, insertCSS } from 'bpmn-js/test/helper';
import {getBusinessObject} from 'bpmn-js/lib/util/ModelUtil';
export let PROPERTIES_PANEL_CONTAINER;
export let CONTAINER;
let PROPERTIES_PANEL_CONTAINER;
export function bootstrapPropertiesPanel(diagram, options, locals) {
return async function() {
CONTAINER = TestContainer.get(this);
const container = TestContainer.get(this);
insertBpmnStyles();
insertCoreStyles();
options.container = CONTAINER;
const createModeler = bootstrapBpmnJS(Modeler, diagram, options, locals);
await act(() => createModeler.call(this));
@ -32,7 +31,7 @@ export function bootstrapPropertiesPanel(diagram, options, locals) {
PROPERTIES_PANEL_CONTAINER = document.createElement('div');
PROPERTIES_PANEL_CONTAINER.classList.add('properties-container');
CONTAINER.appendChild(PROPERTIES_PANEL_CONTAINER);
container.appendChild(PROPERTIES_PANEL_CONTAINER);
return act(() => propertiesPanel.attachTo(PROPERTIES_PANEL_CONTAINER));
});
@ -89,6 +88,11 @@ export function expectSelected(id) {
});
}
export function getPropertiesPanel() {
return PROPERTIES_PANEL_CONTAINER;
}
export function findEntry(id, container) {
return domQuery(`[data-entry-id='${ id }']`, container);
}
@ -101,7 +105,16 @@ export function findSelect(container) {
return domQuery('select', container);
}
export function findTextarea(container) {
return domQuery('textarea', container);
export function changeInput(input, value) {
fireEvent.input(input, { target: { value } });
}
export function findDataObject(element, id) {
const root = getBusinessObject(element).$parent;
return rootElements.find((rootElement) => {
return is(rootElement, 'bpmn:Error')
&& rootElement.get('id').startsWith(`Error_${ errorRef }`);
});
}