DMN selection should be from a dropdown, not by hand entering a process id.
This commit is contained in:
parent
ecb175d727
commit
aeeaf1596e
13
app/app.js
13
app/app.js
|
@ -3,7 +3,7 @@ import {
|
|||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
} from 'bpmn-js-properties-panel';
|
||||
import diagramXML from '../test/spec/bpmn/user_form.bpmn';
|
||||
import diagramXML from '../test/spec/bpmn/diagram.bpmn';
|
||||
import spiffworkflow from './spiffworkflow';
|
||||
import setupFileOperations from './fileOperations';
|
||||
|
||||
|
@ -139,14 +139,20 @@ bpmnModeler.on('callactivity.editor.launch', (newEvent) => {
|
|||
});
|
||||
|
||||
/**
|
||||
* Also can be good to launch an editor for a call activity.
|
||||
* Also can be good to launch an editor for a call activity, or DMN
|
||||
* Not implemented here but imagine opening up a new browser tab
|
||||
* and showing a different process.
|
||||
*/
|
||||
bpmnModeler.on('file.editor.launch', (newEvent) => {
|
||||
console.log(
|
||||
'Open new window to edit file: ',
|
||||
newEvent.fileName
|
||||
newEvent.value
|
||||
);
|
||||
});
|
||||
bpmnModeler.on('dmn.editor.launch', (newEvent) => {
|
||||
console.log(
|
||||
'Open new window to edit DMN table: ',
|
||||
newEvent.value
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -171,6 +177,7 @@ bpmnModeler.on('spiff.options.requested', (event) => {
|
|||
options: [
|
||||
{ label: 'Pizza Special Prices', value: 'pizza_prices' },
|
||||
{ label: 'Topping Prices', value: 'topping_prices' },
|
||||
{ label: 'Test Decision', value: 'test_decision' },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { ListGroup } from '@bpmn-io/properties-panel';
|
||||
import { is, isAny } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import scriptGroup, { SCRIPT_TYPE } from './SpiffScriptGroup';
|
||||
import { SpiffExtensionCalledDecision } from './SpiffExtensionCalledDecision';
|
||||
import { SpiffExtensionTextInput } from './SpiffExtensionTextInput';
|
||||
import instructionsGroup from './SpiffExtensionInstructionsForEndUser';
|
||||
import {
|
||||
|
@ -9,7 +8,8 @@ import {
|
|||
ServiceTaskOperatorSelect, ServiceTaskResultTextInput,
|
||||
} from './SpiffExtensionServiceProperties';
|
||||
import {OPTION_TYPE, SpiffExtensionSelect} from './SpiffExtensionSelect';
|
||||
import {SpiffExtensionLaunchFileEditor} from './SpiffExtensionLaunchFileEditor';
|
||||
import {SpiffExtensionLaunchButton} from './SpiffExtensionLaunchButton';
|
||||
import {SiffExtensionCalledDecision} from './SpiffExtensionCalledDecision';
|
||||
|
||||
const LOW_PRIORITY = 500;
|
||||
|
||||
|
@ -149,10 +149,11 @@ function createUserGroup(element, translate, moddle, commandStack) {
|
|||
name: 'formJsonSchemaFilename',
|
||||
},
|
||||
{
|
||||
component: SpiffExtensionLaunchFileEditor,
|
||||
component: SpiffExtensionLaunchButton,
|
||||
element,
|
||||
name: 'formJsonSchemaFilename',
|
||||
label: translate('Launch Editor'),
|
||||
event: 'file.editor.launch',
|
||||
description: translate('Edit the form description'),
|
||||
},
|
||||
{
|
||||
|
@ -162,14 +163,16 @@ function createUserGroup(element, translate, moddle, commandStack) {
|
|||
component: SpiffExtensionSelect,
|
||||
optionType: OPTION_TYPE.json,
|
||||
label: translate('UI Schema Filename'),
|
||||
event: 'file.editor.launch',
|
||||
description: translate('Rules for displaying the form. (RSJF Schema)'),
|
||||
name: 'formUiSchemaFilename',
|
||||
},
|
||||
{
|
||||
component: SpiffExtensionLaunchFileEditor,
|
||||
component: SpiffExtensionLaunchButton,
|
||||
element,
|
||||
name: 'formUiSchemaFilename',
|
||||
label: translate('Launch Editor'),
|
||||
event: 'file.editor.launch',
|
||||
description: translate('Edit the form schema'),
|
||||
},
|
||||
],
|
||||
|
@ -192,9 +195,21 @@ function createBusinessRuleGroup(element, translate, moddle, commandStack) {
|
|||
element,
|
||||
moddle,
|
||||
commandStack,
|
||||
component: SpiffExtensionCalledDecision,
|
||||
label: translate('Decision Id'),
|
||||
description: translate('Id of the decision'),
|
||||
name: 'calledDecisionId',
|
||||
optionType: OPTION_TYPE.dmn,
|
||||
component: SiffExtensionCalledDecision,
|
||||
label: translate('Select Decision Table'),
|
||||
description: translate(
|
||||
'Select an existing decision table from the list'
|
||||
),
|
||||
},
|
||||
{
|
||||
component: SpiffExtensionLaunchButton,
|
||||
element,
|
||||
name: 'calledDecisionId',
|
||||
label: translate('Launch Editor'),
|
||||
event: 'dmn.editor.launch',
|
||||
description: translate('Modify the Decision Table'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
import { useService } from 'bpmn-js-properties-panel';
|
||||
import { TextFieldEntry } from '@bpmn-io/properties-panel';
|
||||
import { SelectEntry } from '@bpmn-io/properties-panel';
|
||||
|
||||
const SPIFF_PROP = 'spiffworkflow:calledDecisionId';
|
||||
let DMN_OPTIONS = [];
|
||||
|
||||
/**
|
||||
* A generic properties' editor for text input.
|
||||
* Allows you to provide additional SpiffWorkflow extension properties. Just
|
||||
* uses whatever name is provide on the property, and adds or updates it as
|
||||
* needed.
|
||||
*
|
||||
*
|
||||
<bpmn:businessRuleTask id="Activity_0t218za">
|
||||
<bpmn:extensionElements>
|
||||
<spiffworkflow:calledDecisionId>my_id</spiffworkflow:calledDecisionId>
|
||||
</bpmn:extensionElements>
|
||||
</bpmn:businessRuleTask>
|
||||
*
|
||||
* @returns {string|null|*}
|
||||
* Allow selecting a DMN Table from a list of known tables provided through the Event bux.
|
||||
|
||||
<bpmn:businessRuleTask id="Activity_0t218za">
|
||||
<bpmn:extensionElements>
|
||||
<spiffworkflow:calledDecisionId>my_id</spiffworkflow:calledDecisionId>
|
||||
</bpmn:extensionElements>
|
||||
</bpmn:businessRuleTask>
|
||||
|
||||
*/
|
||||
export function SpiffExtensionCalledDecision(props) {
|
||||
export function SiffExtensionCalledDecision(props) {
|
||||
const { element } = props;
|
||||
const { commandStack } = props;
|
||||
const { moddle } = props;
|
||||
const { label } = props;
|
||||
const { description } = props;
|
||||
const { label, description } = props;
|
||||
|
||||
const { name } = props;
|
||||
const { optionType } = props;
|
||||
|
||||
const debounce = useService('debounceInput');
|
||||
const eventBus = useService('eventBus');
|
||||
|
||||
const getPropertyObject = () => {
|
||||
const bizObj = element.businessObject;
|
||||
|
@ -67,15 +67,41 @@ export function SpiffExtensionCalledDecision(props) {
|
|||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<TextFieldEntry
|
||||
id="extension_called_decision"
|
||||
element={element}
|
||||
description={description}
|
||||
label={label}
|
||||
getValue={getValue}
|
||||
setValue={setValue}
|
||||
debounce={debounce}
|
||||
/>
|
||||
);
|
||||
if (DMN_OPTIONS.length === 0) {
|
||||
requestDmnOptions(eventBus, element, commandStack, optionType);
|
||||
}
|
||||
const getOptions = () => {
|
||||
const optionList = [];
|
||||
DMN_OPTIONS.forEach((opt) => {
|
||||
optionList.push({
|
||||
label: opt.label,
|
||||
value: opt.value,
|
||||
});
|
||||
});
|
||||
return optionList;
|
||||
};
|
||||
|
||||
return SelectEntry({
|
||||
id: `extension_${name}`,
|
||||
element,
|
||||
label,
|
||||
description,
|
||||
getValue,
|
||||
setValue,
|
||||
getOptions,
|
||||
debounce,
|
||||
});
|
||||
}
|
||||
|
||||
function requestDmnOptions(eventBus, element, commandStack, optionType) {
|
||||
// Little backwards, but you want to assure you are ready to catch, before you throw
|
||||
// or you risk a race condition.
|
||||
eventBus.once(`spiff.options.returned.dmn`, (event) => {
|
||||
DMN_OPTIONS = event.options;
|
||||
commandStack.execute('element.updateProperties', {
|
||||
element,
|
||||
properties: {},
|
||||
});
|
||||
});
|
||||
eventBus.fire('spiff.options.requested', { eventBus, optionType });
|
||||
}
|
||||
|
|
|
@ -7,15 +7,15 @@ import { getExtensionValue } from '../extensionHelpers';
|
|||
* would like to edit an external file. Hosting application
|
||||
* would need to handle saving the file.
|
||||
*/
|
||||
export function SpiffExtensionLaunchFileEditor(props) {
|
||||
const { element, name } = props;
|
||||
export function SpiffExtensionLaunchButton(props) {
|
||||
const { element, name, event } = props;
|
||||
const eventBus = useService('eventBus');
|
||||
return HeaderButton({
|
||||
className: 'spiffworkflow-properties-panel-button',
|
||||
onClick: () => {
|
||||
const fileName = getExtensionValue(element, name);
|
||||
eventBus.fire('file.editor.launch', {
|
||||
fileName,
|
||||
const value = getExtensionValue(element, name);
|
||||
eventBus.fire(event, {
|
||||
value,
|
||||
});
|
||||
},
|
||||
children: 'Launch Editor',
|
|
@ -54,8 +54,6 @@ export function SpiffExtensionSelect(props) {
|
|||
) {
|
||||
spiffExtensionOptions[optionType] = [];
|
||||
requestOptions(eventBus, element, commandStack, optionType);
|
||||
} else {
|
||||
console.log("Getting here.", spiffExtensionOptions)
|
||||
}
|
||||
const getOptions = () => {
|
||||
const optionList = [];
|
||||
|
@ -85,7 +83,7 @@ export function SpiffExtensionSelect(props) {
|
|||
function requestOptions(eventBus, element, commandStack, optionType) {
|
||||
// Little backwards, but you want to assure you are ready to catch, before you throw
|
||||
// or you risk a race condition.
|
||||
eventBus.once('spiff.options.returned.json', (event) => {
|
||||
eventBus.once(`spiff.options.returned.${optionType}`, (event) => {
|
||||
spiffExtensionOptions[optionType] = event.options;
|
||||
commandStack.execute('element.updateProperties', {
|
||||
element,
|
||||
|
|
|
@ -1,70 +1,91 @@
|
|||
import { query as domQuery } from 'min-dom';
|
||||
import { getBpmnJS } from 'bpmn-js/test/helper';
|
||||
|
||||
import {
|
||||
bootstrapPropertiesPanel, changeInput,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
} from 'bpmn-js-properties-panel';
|
||||
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
|
||||
import {
|
||||
bootstrapPropertiesPanel,
|
||||
changeInput,
|
||||
expectSelected,
|
||||
findEntry,
|
||||
getPropertiesPanel
|
||||
findSelect,
|
||||
getPropertiesPanel,
|
||||
} from './helpers';
|
||||
import {
|
||||
query as domQuery,
|
||||
} from 'min-dom';
|
||||
|
||||
import spiffModdleExtension from '../../app/spiffworkflow/moddle/spiffworkflow.json';
|
||||
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
||||
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
|
||||
import extensions from '../../app/spiffworkflow/extensions';
|
||||
|
||||
describe('Business Rule Properties Panel', function() {
|
||||
describe('Business Rule Properties Panel', function () {
|
||||
const xml = require('./bpmn/diagram.bpmn').default;
|
||||
|
||||
beforeEach(bootstrapPropertiesPanel(xml, {
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
extensions,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflow: spiffModdleExtension
|
||||
},
|
||||
}));
|
||||
beforeEach(
|
||||
bootstrapPropertiesPanel(xml, {
|
||||
debounceInput: false,
|
||||
additionalModules: [
|
||||
extensions,
|
||||
BpmnPropertiesPanelModule,
|
||||
BpmnPropertiesProviderModule,
|
||||
],
|
||||
moddleExtensions: {
|
||||
spiffworkflow: spiffModdleExtension,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
it('should display a text box to select the called decision id', async function() {
|
||||
function addOptionsToEventBus(bpmnModeler) {
|
||||
bpmnModeler.on('spiff.options.requested', (event) => {
|
||||
if (event.optionType === 'dmn') {
|
||||
event.eventBus.fire('spiff.options.returned.dmn', {
|
||||
options: [
|
||||
{ label: 'Calculate Pizza Price', value: 'Decision_Pizza_Price' },
|
||||
{ label: 'Viking Availability', value: 'Decision_Vikings' },
|
||||
{ label: 'Test Decision', value: 'test_decision' },
|
||||
],
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
it('should display a dropdown to select from available decision tables', async function () {
|
||||
const modeler = getBpmnJS();
|
||||
addOptionsToEventBus(modeler);
|
||||
expectSelected('business_rule_task');
|
||||
|
||||
// THEN - a properties panel exists with a section for editing that script
|
||||
let entry = findEntry('extension_called_decision', getPropertiesPanel());
|
||||
const entry = findEntry('extension_calledDecisionId', getPropertiesPanel());
|
||||
expect(entry).to.exist;
|
||||
const textInput = domQuery('input', entry);
|
||||
expect(textInput).to.exist;
|
||||
const selectList = findSelect(entry);
|
||||
expect(selectList).to.exist;
|
||||
});
|
||||
|
||||
it('should update the spiffworkflow:calledDecisionId tag when you modify the called decision text input', async function() {
|
||||
|
||||
it('should update the spiffworkflow:calledDecisionId tag when you modify the called decision select box', async function () {
|
||||
// IF - a script tag is selected, and you change the script in the properties panel
|
||||
const modeler = getBpmnJS();
|
||||
addOptionsToEventBus(modeler);
|
||||
const businessRuleTask = await expectSelected('business_rule_task');
|
||||
const entry = findEntry('extension_called_decision', getPropertiesPanel());
|
||||
const textInput = domQuery('input', entry);
|
||||
changeInput(textInput, 'wonderful');
|
||||
const entry = findEntry('extension_calledDecisionId', getPropertiesPanel());
|
||||
const selectList = findSelect(entry);
|
||||
changeInput(selectList, 'Decision_Pizza_Price');
|
||||
|
||||
// THEN - the script tag in the BPMN Business object / XML is updated as well.
|
||||
const businessObject = getBusinessObject(businessRuleTask);
|
||||
expect(businessObject.extensionElements).to.exist;
|
||||
let element = businessObject.extensionElements.values[0];
|
||||
expect(element.calledDecisionId).to.equal('wonderful');
|
||||
const element = businessObject.extensionElements.values[0];
|
||||
expect(element.calledDecisionId).to.equal('Decision_Pizza_Price');
|
||||
});
|
||||
|
||||
it('should load up the xml and the value for the called decision should match the xml', async function() {
|
||||
it('should load up the xml and the value for the called decision should match the xml', async function () {
|
||||
const businessRuleTask = await expectSelected('business_rule_task');
|
||||
let entry = findEntry('extension_called_decision', getPropertiesPanel());
|
||||
const textInput = domQuery('input', entry);
|
||||
expect(textInput.value).to.equal('test_decision');
|
||||
const entry = findEntry('extension_calledDecisionId', getPropertiesPanel());
|
||||
const selectList = findSelect(entry);
|
||||
expect(selectList.value).to.equal('test_decision');
|
||||
|
||||
// THEN - the script tag in the BPMN Business object / XML is updated as well.
|
||||
let businessObject = getBusinessObject(businessRuleTask);
|
||||
const businessObject = getBusinessObject(businessRuleTask);
|
||||
expect(businessObject.extensionElements).to.exist;
|
||||
let element = businessObject.extensionElements.values[0];
|
||||
const element = businessObject.extensionElements.values[0];
|
||||
expect(element.calledDecisionId).to.equal('test_decision');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue