diff --git a/lib/camunda-cloud/FormsBehavior.js b/lib/camunda-cloud/FormsBehavior.js index d3f1cd3..065f054 100644 --- a/lib/camunda-cloud/FormsBehavior.js +++ b/lib/camunda-cloud/FormsBehavior.js @@ -1,3 +1,5 @@ +import { without } from 'min-dash'; + import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; import { createElement } from '../util/ElementUtil'; @@ -12,6 +14,7 @@ import { getFormDefinition, getRootElement, getUserTaskForm, + isUserTaskFormKey, userTaskFormIdToFormKey } from './util/FormsUtil'; @@ -42,11 +45,9 @@ export default class FormsBehavior extends CommandInterceptor { const rootExtensionElements = rootElement.get('extensionElements'); - const values = rootExtensionElements.get('values').filter((element) => { - return element !== userTaskForm; + modeling.updateModdleProperties(shape, rootExtensionElements, { + values: without(rootExtensionElements.get('values'), userTaskForm) }); - - modeling.updateModdleProperties(shape, rootExtensionElements, { values }); }, true); @@ -114,6 +115,62 @@ export default class FormsBehavior extends CommandInterceptor { }); }, true); + + /** + * Ensure that a user task only has one of + * the following: + * + * 1. zeebe:FormDefinition with zeebe:formId (linked Camunda form) + * 2. zeebe:FormDefinition with zeebe:formKey in the format of camunda-forms:bpmn:UserTaskForm_1 (embedded Camunda form) + * 3. zeebe:FormDefinition with zeebe:formKey (custom form) + */ + this.preExecute('element.updateModdleProperties', function(context) { + const { + element, + moddleElement, + properties + } = context; + + if (!is(moddleElement, 'zeebe:FormDefinition')) { + return; + } + + const { + formId, + formKey + } = properties; + + const userTaskForm = getUserTaskForm(element); + + if (formId) { + if (userTaskForm) { + const rootElement = getRootElement(element), + rootExtensionElements = rootElement.get('extensionElements'); + + modeling.updateModdleProperties(element, rootExtensionElements, { + values: without(rootExtensionElements.get('values'), userTaskForm) + }); + } + + modeling.updateModdleProperties(element, moddleElement, { + formKey: undefined + }); + } else if (formKey) { + if (!isUserTaskFormKey(formKey) && userTaskForm) { + const rootElement = getRootElement(element), + extensionElements = rootElement.get('extensionElements'); + + modeling.updateModdleProperties(element, extensionElements, { + values: without(extensionElements.get('values'), userTaskForm) + }); + } + + modeling.updateModdleProperties(element, moddleElement, { + formId: undefined + }); + } + }, true); + } } diff --git a/test/camunda-cloud/FormDefinitionBehaviorSpec.js b/test/camunda-cloud/FormDefinitionBehaviorSpec.js index cc214a0..82255d7 100644 --- a/test/camunda-cloud/FormDefinitionBehaviorSpec.js +++ b/test/camunda-cloud/FormDefinitionBehaviorSpec.js @@ -20,7 +20,7 @@ describe('camunda-cloud/features/modeling - FormsBehavior', function() { beforeEach(bootstrapCamundaCloudModeler(diagramXML)); - describe('cleanup user task forms', function() { + describe('remove user task form', function() { describe('on remove user task', function() { @@ -150,7 +150,7 @@ describe('camunda-cloud/features/modeling - FormsBehavior', function() { }); - describe('create new user task form', function() { + describe('create user task form', function() { describe('on copy user task', function() { @@ -247,6 +247,96 @@ describe('camunda-cloud/features/modeling - FormsBehavior', function() { }); + + describe('update form definition', function() { + + describe('set form ID', function() { + + it('should remove custom form key', inject(function(elementRegistry, modeling) { + + // given + const userTask = elementRegistry.get('UserTask_11'); + + const formDefinition = getFormDefinition(userTask); + + // when + modeling.updateModdleProperties(userTask, formDefinition, { + formId: 'foobar' + }); + + // then + expect(formDefinition.get('formKey')).not.to.exist; + })); + + + it('should remove user task form', inject(function(canvas, elementRegistry, modeling) { + + // given + const userTask = elementRegistry.get('UserTask_1'); + + const formDefinition = getFormDefinition(userTask); + + // when + modeling.updateModdleProperties(userTask, formDefinition, { + formId: 'foobar' + }); + + // then + expect(formDefinition.get('formKey')).not.to.exist; + + const rootElement = canvas.getRootElement(); + + const userTaskForms = getUserTaskForms(rootElement); + + expect(hasUsertaskForm('UserTaskForm_1', userTaskForms)).to.be.false; + })); + + }); + + + describe('set form key', function() { + + it('should remove form ID', inject(function(elementRegistry, modeling) { + + // given + const userTask = elementRegistry.get('UserTask_12'); + + const formDefinition = getFormDefinition(userTask); + + // when + modeling.updateModdleProperties(userTask, formDefinition, { + formKey: 'foobar' + }); + + // then + expect(formDefinition.get('formId')).not.to.exist; + })); + + + it('should remove user task form', inject(function(canvas, elementRegistry, modeling) { + + // given + const userTask = elementRegistry.get('UserTask_1'); + + const formDefinition = getFormDefinition(userTask); + + // when + modeling.updateModdleProperties(userTask, formDefinition, { + formKey: 'foobar' + }); + + // then + const rootElement = canvas.getRootElement(); + + const userTaskForms = getUserTaskForms(rootElement); + + expect(hasUsertaskForm('UserTaskForm_1', userTaskForms)).to.be.false; + })); + + }); + + }); + }); diff --git a/test/camunda-cloud/process-user-tasks.bpmn b/test/camunda-cloud/process-user-tasks.bpmn index 87c1408..0234a9a 100644 --- a/test/camunda-cloud/process-user-tasks.bpmn +++ b/test/camunda-cloud/process-user-tasks.bpmn @@ -1,5 +1,5 @@ - + { components: [ { label: "field", key: "field" } ] } @@ -58,6 +58,16 @@ + + + + + + + + + + @@ -106,8 +116,15 @@ + + + + + + + - +