diff --git a/src/provider/zeebe/properties/FormProps.js b/src/provider/zeebe/properties/FormProps.js
index dd0f77af2..958e627d9 100644
--- a/src/provider/zeebe/properties/FormProps.js
+++ b/src/provider/zeebe/properties/FormProps.js
@@ -3,10 +3,18 @@ import {
is
} from 'bpmn-js/lib/util/ModelUtil';
-import { TextAreaEntry, isTextAreaEntryEdited } from '@bpmn-io/properties-panel';
+import {
+ SelectEntry,
+ TextFieldEntry,
+ TextAreaEntry,
+ isSelectEntryEdited,
+ isTextFieldEntryEdited,
+ isTextAreaEntryEdited
+} from '@bpmn-io/properties-panel';
import {
- createElement
+ createElement,
+ nextId
} from '../../../utils/ElementUtil';
import {
@@ -14,11 +22,9 @@ import {
} from '../../../utils/ExtensionElementsUtil';
import {
- nextId
-} from '../../../utils/ElementUtil';
-
-import {
- find, without
+ find,
+ isUndefined,
+ without
} from 'min-dash';
import {
@@ -35,47 +41,164 @@ export function FormProps(props) {
return [];
}
- return [
+ const entries = [];
+
+ entries.push(
+ {
+ id: 'formType',
+ component: ,
+ isEdited: isSelectEntryEdited
+ },
{
id: 'formConfiguration',
- component: ,
+ component: ,
isEdited: isTextAreaEntryEdited
- }
- ];
+ },
+ {
+ id: 'customFormKey',
+ component: ,
+ isEdited: isTextFieldEntryEdited
+ },
+ );
+
+ return entries;
}
-function FormProperty(props) {
+
+function FormType(props) {
+
const {
element
} = props;
+ const translate = useService('translate');
const injector = useService('injector');
+ const formHelper = injector.invoke(FormHelper);
- const debounce = useService('debounceInput');
- const translate = useService('translate');
+ const getValue = () => {
+ const formDefinition = formHelper.getFormDefinition(element);
+ const userTaskForm = formHelper.getUserTaskForm(element);
- const formHelper = injector.invoke(FormHelper);
+ if (formDefinition) {
+
+ if (userTaskForm) {
+ return 'formKey';
+ }
+
+ return 'customFormKey';
+ }
+
+ return '';
+ };
- const getValue = () => formHelper.get(element);
+ const setValue = (value) => {
- const setValue = (value) => formHelper.set(element, value);
+ formHelper.resetForm(element);
- return TextAreaEntry({
+ if (value === 'formKey') {
+ formHelper.setUserTaskForm(element, '');
+
+ } else if (value === 'customFormKey') {
+ formHelper.setFormDefinition(element, '');
+ }
+ };
+
+ const getOptions = () => {
+ return [
+ { value: '', label: translate('') },
+ { value: 'formKey', label: translate('Camunda Forms') },
+ { value: 'customFormKey', label: translate('Custom Key') },
+ ];
+ };
+
+ return SelectEntry({
element,
- id: 'formConfiguration',
- label: translate('Form JSON configuration'),
- rows: 4,
+ id: 'formType',
+ label: translate('Type'),
getValue,
setValue,
- debounce
+ getOptions
});
}
+function FormConfiguration(props) {
+ const {
+ element
+ } = props;
+
+ const injector = useService('injector');
+ const debounce = useService('debounceInput');
+ const translate = useService('translate');
+ const formHelper = injector.invoke(FormHelper);
+
+ const getValue = () => {
+ const userTaskForm = formHelper.getUserTaskForm(element);
+ return userTaskForm.get('body');
+ };
+
+ const setValue = (value) => {
+ formHelper.setUserTaskForm(element, value);
+ };
+
+ if (isCamundaForm(element, formHelper)) {
+ return TextAreaEntry({
+ element,
+ id: 'formConfiguration',
+ label: translate('Form JSON configuration'),
+ rows: 4,
+ getValue,
+ setValue,
+ debounce
+ });
+ }
+}
+
+
+function CustomFormKey(props) {
+ const {
+ element
+ } = props;
+
+ const injector = useService('injector');
+ const debounce = useService('debounceInput');
+ const translate = useService('translate');
+ const formHelper = injector.invoke(FormHelper);
+
+ const getValue = () => {
+ const formDefinition = formHelper.getFormDefinition(element);
+ return formDefinition.get('formKey');
+ };
+
+ const setValue = (value) => {
+ formHelper.setFormDefinition(element, value);
+ };
+
+ if (isCustomKey(element, formHelper)) {
+ return TextFieldEntry({
+ element,
+ id: 'customFormKey',
+ label: translate('Form Key'),
+ getValue,
+ setValue,
+ debounce
+ });
+ }
+
+}
+
const USER_TASK_FORM_PREFIX = 'userTaskForm_';
function FormHelper(bpmnFactory, commandStack) {
+ function getFormDefinition(element) {
+ const businessObject = getBusinessObject(element);
+
+ const formDefinitions = getExtensionElementsList(businessObject, 'zeebe:FormDefinition');
+
+ return formDefinitions[0];
+ }
+
function getUserTaskForm(element, parent) {
const rootElement = parent || getRootElement(element);
@@ -83,7 +206,7 @@ function FormHelper(bpmnFactory, commandStack) {
// (1) get form definition from user task
const formDefinition = getFormDefinition(element);
- if (!formDefinition) {
+ if (isUndefined(formDefinition)) {
return;
}
@@ -95,131 +218,147 @@ function FormHelper(bpmnFactory, commandStack) {
return userTaskForm;
}
- function getFormDefinition(element) {
- const businessObject = getBusinessObject(element);
+ function ensureTaskForm(element, values) {
- const formDefinitions = getExtensionElementsList(businessObject, 'zeebe:FormDefinition');
+ let commands = [];
- return formDefinitions[0];
- }
+ const rootElement = getRootElement(element);
- function setUserTaskForm(element, body) {
+ // (1) ensure root element extension elements
+ let rootExtensionElements = rootElement.get('extensionElements');
- const businessObject = getBusinessObject(element),
- rootElement = getRootElement(element);
+ if (!rootExtensionElements) {
+ rootExtensionElements = createElement(
+ 'bpmn:ExtensionElements',
+ { values: [] },
+ rootElement,
+ bpmnFactory
+ );
- let commands = [],
- userTaskForm,
- formId;
+ commands.push(
+ UpdateModdlePropertiesCmd(element, rootElement, {
+ extensionElements: rootExtensionElements,
+ })
+ );
+ }
- // (1) ensure extension elements
- let extensionElements = businessObject.get('extensionElements');
+ // (2) ensure user task form
+ let userTaskForm = getUserTaskForm(element);
- if (!extensionElements) {
- extensionElements = createElement(
- 'bpmn:ExtensionElements',
- { values: [] },
- businessObject,
+ // (2.1) create user task form if doesn't exist
+ if (!userTaskForm) {
+ userTaskForm = createUserTaskForm(
+ values,
+ rootExtensionElements,
bpmnFactory
);
commands.push(
- UpdateModdlePropertiesCmd(element, businessObject, {
- extensionElements: extensionElements,
+ UpdateModdlePropertiesCmd(element, rootExtensionElements,{
+ values: [ ...rootExtensionElements.get('values'), userTaskForm ]
})
);
}
- // (2) ensure root element extension elements
- let rootExtensionElements = rootElement.get('extensionElements');
+ commands.push(UpdateModdlePropertiesCmd(element, userTaskForm, values));
- if (!rootExtensionElements) {
- rootExtensionElements = createElement(
+ return commands;
+ }
+
+ function ensureFormDefinition(element, customFormKey) {
+ const businessObject = getBusinessObject(element);
+
+ let commands = [];
+
+ // (1) ensure extension elements
+ let extensionElements = businessObject.get('extensionElements');
+
+ if (isUndefined(extensionElements)) {
+ extensionElements = createElement(
'bpmn:ExtensionElements',
{ values: [] },
- rootElement,
+ businessObject,
bpmnFactory
);
commands.push(
- UpdateModdlePropertiesCmd(element, rootElement, {
- extensionElements: rootExtensionElements,
+ UpdateModdlePropertiesCmd(element, businessObject, {
+ extensionElements: extensionElements,
})
);
}
- // (3) ensure form definition
+ // (2) ensure form definition
let formDefinition = getFormDefinition(element);
+ // (2.1) create if doesn't exist
if (!formDefinition) {
- formId = createFormId();
+ let formKey = customFormKey;
+
+ if (isUndefined(formKey)) {
+ const formId = createFormId();
+ formKey = createFormKey(formId);
+ }
formDefinition = createFormDefinition(
{
- formKey: createFormKey(formId)
+ formKey
},
extensionElements,
bpmnFactory
);
- commands.push({
- cmd: 'element.updateModdleProperties',
- context: {
- element,
- moddleElement: extensionElements,
- properties: {
- values: [ ...extensionElements.get('values'), formDefinition ]
- }
- }
- });
+ commands.push(
+ UpdateModdlePropertiesCmd(element, extensionElements, {
+ values: [ ...extensionElements.get('values'), formDefinition ]
+ })
+ );
}
- formId = resolveFormId(formDefinition.get('formKey'));
+ // (2.2) update existing form definition with custom key
+ else if (customFormKey) {
+ commands.push(
+ UpdateModdlePropertiesCmd(element, formDefinition, {
+ formKey: customFormKey
+ })
+ );
+ }
- // (4) ensure user task form
- userTaskForm = getUserTaskForm(element);
+ return {
+ formId: resolveFormId(formDefinition.get('formKey')),
+ commands
+ };
+ }
- if (!userTaskForm) {
- userTaskForm = createUserTaskForm(
- {
- id: formId,
- body: body
- },
- rootExtensionElements,
- bpmnFactory
- );
+ function setFormDefinition(element, customFormKey) {
- commands.push({
- cmd: 'element.updateModdleProperties',
- context: {
- element,
- moddleElement: rootExtensionElements,
- properties: {
- values: [ ...rootExtensionElements.get('values'), userTaskForm ]
- }
- }
- });
- }
+ const {
+ commands
+ } = ensureFormDefinition(element, customFormKey);
+
+ commandStack.execute('properties-panel.multi-command-executor', commands);
+ }
- // (5) update user task form
- commands.push(UpdateModdlePropertiesCmd(element, userTaskForm, {
- body
- }));
+ function setUserTaskForm(element, value) {
- return commands;
+ const {
+ formId,
+ commands: formDefCommands
+ } = ensureFormDefinition(element);
+
+ const userTaskCommands = ensureTaskForm(element, { id:formId, body:value });
+ const commands = formDefCommands.concat(userTaskCommands);
+ commandStack.execute('properties-panel.multi-command-executor', commands);
}
- function unsetUserTaskForm(element) {
+ function unsetFormDefinition(element) {
const businessObject = getBusinessObject(element),
- rootElement = getRootElement(element),
- extensionElements = businessObject.get('extensionElements'),
- rootExtensionElements = rootElement.get('extensionElements');
+ extensionElements = businessObject.get('extensionElements');
let commands = [];
- // (1) remove form definition
const formDefinition = getFormDefinition(element);
if (!formDefinition) {
@@ -228,38 +367,37 @@ function FormHelper(bpmnFactory, commandStack) {
let values = without(extensionElements.get('values'), formDefinition);
- commands.push({
- cmd: 'element.updateModdleProperties',
- context: {
- element,
- moddleElement: extensionElements,
- properties: {
- values
- }
- }
- });
+ commands.push(
+ UpdateModdlePropertiesCmd(element, extensionElements, { values })
+ );
+
+ return commands;
+ }
+
+ function resetForm(element) {
+
+ const rootElement = getRootElement(element),
+ rootExtensionElements = rootElement.get('extensionElements');
+
+ // (1) remove form definition
+ const commands = unsetFormDefinition(element);
// (2) remove referenced user task form
const userTaskForm = getUserTaskForm(element);
if (!userTaskForm) {
- return commands;
+ commandStack.execute('properties-panel.multi-command-executor', commands);
+ return;
}
- values = without(rootExtensionElements.get('values'), userTaskForm);
+ const values = without(rootExtensionElements.get('values'), userTaskForm);
- commands.push({
- cmd: 'element.updateModdleProperties',
- context: {
- element,
- moddleElement: rootExtensionElements,
- properties: {
- values
- }
- }
- });
+ commands.push(
+ UpdateModdlePropertiesCmd(element, rootExtensionElements, { values })
+ );
+
+ commandStack.execute('properties-panel.multi-command-executor', commands);
- return commands;
}
function createFormKey(formId) {
@@ -312,28 +450,12 @@ function FormHelper(bpmnFactory, commandStack) {
return parent;
}
- function get(element) {
- const value = getUserTaskForm(element);
-
- return value && value.body || '';
- }
-
- function set(element, body) {
-
- body = body && body.trim();
-
- const commands = (
- body
- ? setUserTaskForm(element, body)
- : unsetUserTaskForm(element)
- );
-
- commandStack.execute('properties-panel.multi-command-executor', commands);
- }
-
return {
- get,
- set
+ getFormDefinition,
+ getUserTaskForm,
+ setFormDefinition,
+ setUserTaskForm,
+ resetForm
};
}
@@ -352,4 +474,18 @@ function UpdateModdlePropertiesCmd(element, businessObject, newProperties) {
properties: newProperties
}
};
+}
+
+function isCamundaForm(element, formHelper) {
+ const formDefinition = formHelper.getFormDefinition(element);
+ const userTaskForm = formHelper.getUserTaskForm(element);
+
+ return formDefinition && userTaskForm;
+}
+
+function isCustomKey(element, formHelper) {
+ const formDefinition = formHelper.getFormDefinition(element);
+ const userTaskForm = formHelper.getUserTaskForm(element);
+
+ return formDefinition && !userTaskForm;
}
\ No newline at end of file
diff --git a/test/spec/provider/zeebe/Forms.bpmn b/test/spec/provider/zeebe/Forms.bpmn
index e9afb64fb..800241ab5 100644
--- a/test/spec/provider/zeebe/Forms.bpmn
+++ b/test/spec/provider/zeebe/Forms.bpmn
@@ -1,24 +1,32 @@
-
+
{}
-
+
+
+
+
+
+
-
+
+
+
+
diff --git a/test/spec/provider/zeebe/Forms.spec.js b/test/spec/provider/zeebe/Forms.spec.js
index 8e586ec4c..c87ee9d82 100644
--- a/test/spec/provider/zeebe/Forms.spec.js
+++ b/test/spec/provider/zeebe/Forms.spec.js
@@ -67,99 +67,211 @@ describe('provider/zeebe - Forms', function() {
describe('zeebe:userTaskForm', function() {
- it('should display', inject(async function(elementRegistry, selection) {
+ describe('form type', function() {
- // given
- const userTask = elementRegistry.get('WITH_FORM');
+ it('should display - custom key', inject(async function(elementRegistry, selection) {
- // when
- await act(() => {
- selection.select(userTask);
- });
+ // given
+ const userTask = elementRegistry.get('WITH_CAMUNDA_FORM');
- const formInput = getFormInput(container);
+ // when
+ await act(() => {
+ selection.select(userTask);
+ });
- // then
- expect(formInput).to.exist;
+ const formInput = getFormInput(container);
- expect(formInput.value).to.equal('{}');
- }));
+ // then
+ expect(formInput).to.exist;
+ expect(formInput.value).to.equal('formKey');
+ }));
- it('should display empty', inject(async function(elementRegistry, selection) {
- // given
- const userTask = elementRegistry.get('NO_FORM');
+ it('should display - camunda form', inject(async function(elementRegistry, selection) {
- // when
- await act(() => {
- selection.select(userTask);
- });
+ // given
+ const userTask = elementRegistry.get('WITH_CUSTOM_KEY');
- const formInput = getFormInput(container);
+ // when
+ await act(() => {
+ selection.select(userTask);
+ });
- // then
- expect(formInput).to.exist;
+ const formInput = getFormInput(container);
- expect(formInput.value).to.equal('');
- }));
+ // then
+ expect(formInput).to.exist;
+ expect(formInput.value).to.equal('customFormKey');
+ }));
- it('should update', inject(async function(elementRegistry, selection) {
- // given
- const userTask = elementRegistry.get('WITH_FORM');
+ it('should display - empty', inject(async function(elementRegistry, selection) {
- await act(() => {
- selection.select(userTask);
- });
+ // given
+ const userTask = elementRegistry.get('NO_FORM');
- const formInput = getFormInput(container);
+ // when
+ await act(() => {
+ selection.select(userTask);
+ });
- // when
- changeInput(formInput, '{ "a": 1 }');
+ const formInput = getFormInput(container);
- // then
- expectForm(userTask, '{ "a": 1 }');
- }));
+ // then
+ expect(formInput).to.exist;
+ expect(formInput.value).to.equal('');
+ }));
- it('should remove', inject(async function(elementRegistry, selection) {
- // given
- const userTask = elementRegistry.get('WITH_FORM');
+ it('should update - empty', inject(async function(elementRegistry, selection) {
- await act(() => {
- selection.select(userTask);
- });
+ // given
+ const userTask = elementRegistry.get('WITH_CAMUNDA_FORM');
- const formInput = getFormInput(container);
+ await act(() => {
+ selection.select(userTask);
+ });
- // when
- changeInput(formInput, '');
+ const formInput = getFormInput(container);
- // then
- expectForm(userTask, null);
- }));
+ // when
+ changeInput(formInput, '');
+ // then
- it('should add', inject(async function(elementRegistry, selection) {
+ // expect user task form not to exist
+ const formDefinition = getFormDefinition(userTask);
+ expect(formDefinition).to.not.exist;
- // given
- const userTask = elementRegistry.get('NO_FORM');
+ // expect form definnition not to exist
+ const rootElement = getRootElement(userTask);
+ const forms = getExtensionElementsList(rootElement, 'zeebe:UserTaskForm');
+ expect(forms).to.have.lengthOf(0);
+ }));
- await act(() => {
- selection.select(userTask);
- });
- const formInput = getFormInput(container);
+ it('should update - camunda form', inject(async function(elementRegistry, selection) {
- // when
- changeInput(formInput, '{}');
+ // given
+ const userTask = elementRegistry.get('NO_FORM');
+
+ await act(() => {
+ selection.select(userTask);
+ });
+
+ const formInput = getFormInput(container);
+
+ // when
+ changeInput(formInput, 'formKey');
+
+ // then
+ expectForm(userTask, '');
+ }));
+
+
+ it('should update - custom key', inject(async function(elementRegistry, selection) {
+
+ // given
+ const userTask = elementRegistry.get('NO_FORM');
+
+ await act(() => {
+ selection.select(userTask);
+ });
+
+ const formInput = getFormInput(container);
+
+ // when
+ changeInput(formInput, 'customFormKey');
+
+ // then
+ expectFormKey(userTask, '');
+ }));
+
+ });
+
+
+ describe('camunda form', function() {
+
+ it('should display', inject(async function(elementRegistry, selection) {
+
+ // given
+ const userTask = elementRegistry.get('WITH_CAMUNDA_FORM');
+
+ // when
+ await act(() => {
+ selection.select(userTask);
+ });
+
+ const formConfig = getFormConfig(container);
+
+ // then
+ expect(formConfig).to.exist;
+ }));
+
+
+ it('should update', inject(async function(elementRegistry, selection) {
+
+ // given
+ const userTask = elementRegistry.get('WITH_CAMUNDA_FORM');
+
+ await act(() => {
+ selection.select(userTask);
+ });
+
+ const formConfig = getFormConfig(container);
+
+ // when
+ changeInput(formConfig, '{ "a": 1 }');
+
+ // then
+ expectForm(userTask, '{ "a": 1 }');
+ }));
+
+ });
+
+
+ describe('custom key', function() {
+
+ it('should display', inject(async function(elementRegistry, selection) {
+
+ // given
+ const userTask = elementRegistry.get('WITH_CUSTOM_KEY');
+
+ // when
+ await act(() => {
+ selection.select(userTask);
+ });
+
+ const formKey = getCustomKey(container);
+
+ // then
+ expect(formKey).to.exist;
+ }));
+
+
+ it('should update', inject(async function(elementRegistry, selection) {
+
+ // given
+ const userTask = elementRegistry.get('WITH_CUSTOM_KEY');
+
+ await act(() => {
+ selection.select(userTask);
+ });
+
+ const formKey = getCustomKey(container);
+
+ // when
+ changeInput(formKey, 'customKey');
+
+ // then
+ expectFormKey(userTask, 'customKey');
+ }));
+
+ });
- // then
- expectForm(userTask, '{}');
- }));
});
@@ -169,27 +281,35 @@ describe('provider/zeebe - Forms', function() {
// helpers /////////////////////
function getFormInput(container) {
+ return domQuery('select[name=formType]', container);
+}
+
+function getFormConfig(container) {
return domQuery('textarea[name=formConfiguration]', container);
}
-function expectForm(element, body) {
+function getCustomKey(container) {
+ return domQuery('input[name=customFormKey]', container);
+}
- // (1) get form definition from user task
+function expectFormKey(element, key) {
const formDefinition = getFormDefinition(element);
- // (2.1) assume removed, if no body
- if (!body) {
- expect(formDefinition).not.to.exist;
+ expect(formDefinition).to.exist;
+ expect(formDefinition.formKey).to.eql(key);
+}
- return;
- }
+function expectForm(element, body) {
+
+ // (1) get form definition from user task
+ const formDefinition = getFormDefinition(element);
- // (2.2) assume existing
+ // (1.2) assume existing
expect(formDefinition).to.exist;
const rootElement = getRootElement(element);
- // (3) assume corresponding task form on root element
+ // (2) assume corresponding task form on root element
const formKey = formDefinition.get('formKey');
const form = findUserTaskForm(formKey, rootElement);