Assume established naming conventions over requiring a form schema and ui schema each time as separate inputs. Making this one dropdown for the user form instead of two.

Assure there is always an empty option in the dropdown list, so people have
the ability to re-select nothing if they choose to do so.

Provide a way to override the default behavior when a response is provided back to a generic launch button.
This commit is contained in:
danfunk 2023-09-06 17:38:38 -04:00
parent 53f45dbaa8
commit 5fcb47125a
5 changed files with 66 additions and 35 deletions

View File

@ -160,8 +160,8 @@ bpmnModeler.on('spiff.dmn.edit', (newEvent) => {
* Also handy to get a list of available files that can be used in a given
* context, say json files for a form, or a DMN file for a BusinessRuleTask
*/
bpmnModeler.on('spiff.json_files.requested', (event) => {
event.eventBus.fire('spiff.json_files.returned', {
bpmnModeler.on('spiff.json_schema_files.requested', (event) => {
event.eventBus.fire('spiff.json_schema_files.returned', {
options: [
{ label: 'pizza_form.json', value: 'pizza_form.json' },
{ label: 'credit_card_form.json', value: 'credit_card_form.json' },

View File

@ -9,13 +9,14 @@ import {
ServiceTaskParameterArray,
ServiceTaskOperatorSelect, ServiceTaskResultTextInput,
} from './SpiffExtensionServiceProperties';
import {OPTION_TYPE, SpiffExtensionSelect} from './SpiffExtensionSelect';
import {OPTION_TYPE, spiffExtensionOptions, SpiffExtensionSelect} from './SpiffExtensionSelect';
import {SpiffExtensionLaunchButton} from './SpiffExtensionLaunchButton';
import {SpiffExtensionTextArea} from './SpiffExtensionTextArea';
import {SpiffExtensionTextInput} from './SpiffExtensionTextInput';
import {SpiffExtensionCheckboxEntry} from './SpiffExtensionCheckboxEntry';
import {hasEventDefinition} from 'bpmn-js/lib/util/DiUtil';
import { PropertyDescription } from 'bpmn-js-properties-panel/';
import {setExtensionValue} from "../extensionHelpers";
const LOW_PRIORITY = 500;
@ -203,6 +204,17 @@ function ScriptValenceCheckbox(props) {
* @returns entries
*/
function createUserGroup(element, translate, moddle, commandStack) {
const updateExtensionProperties = (element, name, value, moddle, commandStack) => {
const uiName = value.replace('schema\.json', 'uischema\.json')
setExtensionValue(element, 'formJsonSchemaFilename', value, moddle, commandStack);
setExtensionValue(element, 'formUiSchemaFilename', uiName, moddle, commandStack);
const matches = spiffExtensionOptions[OPTION_TYPE.json_schema_files].filter((opt) => opt.value === value);
if (matches.length === 0) {
spiffExtensionOptions[OPTION_TYPE.json_schema_files].push({label: value, value: value});
}
}
return {
id: 'user_task_properties',
label: translate('Web Form (with Json Schemas)'),
@ -212,7 +224,7 @@ function createUserGroup(element, translate, moddle, commandStack) {
moddle,
commandStack,
component: SpiffExtensionSelect,
optionType: OPTION_TYPE.json_files,
optionType: OPTION_TYPE.json_schema_files,
name: 'formJsonSchemaFilename',
label: translate('JSON Schema Filename'),
description: translate('Form Description (RSJF)'),
@ -220,29 +232,14 @@ function createUserGroup(element, translate, moddle, commandStack) {
{
component: SpiffExtensionLaunchButton,
element,
moddle,
commandStack,
name: 'formJsonSchemaFilename',
label: translate('Launch Editor'),
event: 'spiff.file.edit',
description: translate('Edit the form description'),
},
{
element,
moddle,
commandStack,
component: SpiffExtensionSelect,
optionType: OPTION_TYPE.json_files,
label: translate('UI Schema Filename'),
event: 'spiff.file.edit',
description: translate('Rules for displaying the form. (RSJF Schema)'),
name: 'formUiSchemaFilename',
},
{
component: SpiffExtensionLaunchButton,
element,
name: 'formUiSchemaFilename',
label: translate('Launch Editor'),
event: 'spiff.file.edit',
description: translate('Edit the form schema'),
listenEvent: 'spiff.jsonSchema.update',
listenFunction: updateExtensionProperties,
description: translate('Edit the form schema')
},
],
};

View File

@ -8,7 +8,7 @@ import {getExtensionValue, setExtensionValue} from '../extensionHelpers';
* update the value and send it back.
*/
export function SpiffExtensionLaunchButton(props) {
const { element, name, event, listenEvent } = props;
const { element, name, event, listenEvent, listenFunction } = props;
const eventBus = useService('eventBus');
return HeaderButton({
className: 'spiffworkflow-properties-panel-button',
@ -28,7 +28,11 @@ export function SpiffExtensionLaunchButton(props) {
const { commandStack, moddle } = props;
// Listen for a response, to update the script.
eventBus.once(listenEvent, (response) => {
setExtensionValue(element, name, response.value, moddle, commandStack);
if(listenFunction) {
listenFunction(element, name, response.value, moddle, commandStack);
} else {
setExtensionValue(element, name, response.value, moddle, commandStack);
}
});
}

View File

@ -5,10 +5,10 @@ import {
setExtensionValue,
} from '../extensionHelpers';
const spiffExtensionOptions = {};
export const spiffExtensionOptions = {};
export const OPTION_TYPE = {
json_files: 'json_files',
json_schema_files: 'json_schema_files',
dmn_files: 'dmn_files',
};
@ -52,6 +52,10 @@ export function SpiffExtensionSelect(props) {
}
const getOptions = () => {
const optionList = [];
optionList.push({
label: '',
value: '',
});
if (
optionType in spiffExtensionOptions &&
spiffExtensionOptions[optionType] !== null
@ -81,7 +85,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.${optionType}.returned`, (event) => {
eventBus.on(`spiff.${optionType}.returned`, (event) => {
spiffExtensionOptions[optionType] = event.options;
});
eventBus.fire(`spiff.${optionType}.requested`, { eventBus });

View File

@ -18,7 +18,7 @@ import {
} from './helpers';
import extensions from '../../app/spiffworkflow/extensions';
import {query as domQuery} from 'min-dom';
import {default as diagram_xml} from './bpmn/diagram.bpmn';
describe('Properties Panel for User Tasks', function () {
const user_form_xml = require('./bpmn/user_form.bpmn').default;
@ -30,8 +30,8 @@ describe('Properties Panel for User Tasks', function () {
});
function addOptionsToEventBus(bpmnModeler) {
bpmnModeler.on('spiff.json_files.requested', (event) => {
event.eventBus.fire('spiff.json_files.returned', {
bpmnModeler.on('spiff.json_schema_files.requested', (event) => {
event.eventBus.fire('spiff.json_schema_files.returned', {
options: [
{ label: 'pizza_form.json', value: 'pizza_form.json' },
{ label: 'credit_card_form.json', value: 'credit_card_form.json' },
@ -106,9 +106,35 @@ describe('Properties Panel for User Tasks', function () {
const formJsonSchemaFilenameEntry = findEntry('extension_formJsonSchemaFilename', group);
const formJsonSchemaFilenameInput = findSelect(formJsonSchemaFilenameEntry);
expect(formJsonSchemaFilenameInput.value).to.equal('give_me_a_number_form.json');
const formUiSchemaFilenameEntry = findEntry('extension_formUiSchemaFilename', group);
const formUiSchemaFilenameInput = findSelect(formUiSchemaFilenameEntry);
expect(formUiSchemaFilenameInput.value).to.equal('number_form_schema.json');
});
it('should update both the json and ui extensions if the json file is set', async function () {
await preparePropertiesPanelWithXml(diagram_xml)();
const modeler = getBpmnJS();
addOptionsToEventBus(modeler);
const userElement = await expectSelected('task_confirm');
const group = findGroupEntry('user_task_properties', container);
const button = findButton(
'launch_editor_button_formJsonSchemaFilename',
group
);
expect(button).to.exist;
let launchEvent;
let eventBus = modeler.get('eventBus');
eventBus.on('spiff.file.edit', function (event) {
launchEvent = event;
});
await pressButton(button);
expect(launchEvent.value).to.exist;
eventBus.fire('spiff.jsonSchema.update', {
value: 'new-schema.json',
});
const jsonFile = getExtensionValue(userElement, 'formJsonSchemaFilename');
const uiFile = getExtensionValue(userElement, 'formUiSchemaFilename');
expect(jsonFile).to.equal('new-schema.json');
expect(uiFile).to.equal('new-uischema.json');
});
it('should allow you to change the instructions to the end user', async function () {