diff --git a/src/cloud-element-templates/Condition.js b/src/cloud-element-templates/Condition.js index 114165b4..04777db6 100644 --- a/src/cloud-element-templates/Condition.js +++ b/src/cloud-element-templates/Condition.js @@ -6,8 +6,14 @@ import { getPropertyValue } from './util/propertyUtil'; export function applyConditions(element, elementTemplate) { const { properties } = elementTemplate; - const filteredProperties = properties.filter(property => { - return isConditionMet(element, properties, property); + let filteredProperties = []; + + properties.forEach(property => { + if (isConditionMet(element, properties, property)) { + filteredProperties.push( + applyDropdownConditions(element, properties, property) + ); + } }); return { @@ -16,6 +22,20 @@ export function applyConditions(element, elementTemplate) { }; } +export function applyDropdownConditions(element, properties, property) { + const { type, choices } = property; + + if (type != 'Dropdown') + return property; + + else { + return { + ...property, + choices: choices.filter(choice => isConditionMet(element, properties, choice)) + }; + } +} + export function isConditionMet(element, properties, property) { const { condition } = property; diff --git a/test/spec/cloud-element-templates/ElementTemplateConditionChecker.spec.js b/test/spec/cloud-element-templates/ElementTemplateConditionChecker.spec.js index ca8098f3..52e3ed25 100644 --- a/test/spec/cloud-element-templates/ElementTemplateConditionChecker.spec.js +++ b/test/spec/cloud-element-templates/ElementTemplateConditionChecker.spec.js @@ -2,6 +2,7 @@ import TestContainer from 'mocha-test-container-support'; import { bootstrapModeler, + bootstrapPropertiesPanel, inject } from 'test/TestHelper'; @@ -17,12 +18,18 @@ import messageDiagramXML from './fixtures/condition-message.bpmn'; import template from './fixtures/condition.json'; import messageTemplates from './fixtures/condition-message.json'; +import dropdownConditions from './fixtures/condition-dropdown.json'; import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil'; import { findExtension, findMessage, findZeebeSubscription } from 'src/cloud-element-templates/Helper'; import ElementTemplatesConditionChecker from 'src/cloud-element-templates/ElementTemplatesConditionChecker'; import { getBpmnJS } from 'bpmn-js/test/helper'; import { isString } from 'min-dash'; +import { + query as domQuery +} from 'min-dom'; + +import { act } from '@testing-library/preact'; describe('provider/cloud-element-templates - ElementTemplatesConditionChecker', function() { @@ -1116,6 +1123,147 @@ describe('provider/cloud-element-templates - ElementTemplatesConditionChecker', }) ); }); + + + describe('conditional dropdown choices', function() { + + beforeEach(bootstrapPropertiesPanel(diagramXML, { + container: container, + modules: [ + coreModule, + elementTemplatesModule, + modelingModule, + ElementTemplatesConditionChecker, + BpmnPropertiesPanelModule + ], + moddleExtensions: { + zeebe: zeebeModdlePackage + } + })); + + beforeEach(inject(function(elementTemplates) { + elementTemplates.set([ dropdownConditions ]); + })); + + + it('should add conditional entries', inject( + async function(elementRegistry, modeling, selection) { + + // given + const element = elementRegistry.get('Task_1'); + + changeTemplate(element, dropdownConditions); + + // when + await act(() => { + selection.select(element); + modeling.updateProperties(element, { name: 'foo' }); + }); + + // then + expectDropdownOptions(container, 2, 'foo'); + }) + ); + + + it('should switch between conditional properties', inject( + async function(elementRegistry, modeling, selection) { + + // given + const element = elementRegistry.get('Task_1'); + + changeTemplate(element, dropdownConditions); + + // when + await act(() => { + selection.select(element); + modeling.updateProperties(element, { name: 'foo' }); + }); + + // then + expectDropdownOptions(container, 2, 'foo'); + + // when + await act(() => + modeling.updateProperties(element, { name: 'bar' }) + ); + + // then + expectDropdownOptions(container, 2, 'bar'); + }) + ); + + + it('undo', inject(async function(commandStack, elementRegistry, modeling, selection) { + + // given + const element = elementRegistry.get('Task_1'); + + changeTemplate(element, dropdownConditions); + + // when + await act(() => { + selection.select(element); + modeling.updateProperties(element, { name: 'foo' }); + }); + + // assume + expectDropdownOptions(container, 2, 'foo'); + + // when + await act(() => commandStack.undo()); + + // then + expectDropdownOptions(container, 1, 'foobar'); + })); + + + it('redo', inject(async function(commandStack, elementRegistry, modeling, selection) { + + // given + const element = elementRegistry.get('Task_1'); + + changeTemplate(element, dropdownConditions); + + // when + await act(() => { + selection.select(element); + modeling.updateProperties(element, { name: 'foo' }); + }); + + // when + await act(() => commandStack.undo()); + + // then + expectDropdownOptions(container, 1, 'foobar'); + + // when + await act(() => commandStack.redo()); + + // then + expectDropdownOptions(container, 2, 'foo'); + })); + + + it('should remove conditional entries', inject( + async function(elementRegistry, modeling, selection) { + + // given + const element = elementRegistry.get('Task_1'); + + changeTemplate(element, dropdownConditions); + + // when + await act(() => { + selection.select(element); + modeling.updateProperties(element, { name: '' }); + }); + + // then + expectDropdownOptions(container, 1, 'foobar'); + }) + ); + }); }); @@ -1178,4 +1326,11 @@ function expectZeebePropertyValue(businessObject, value) { expect(zeebeProperties).to.exist; expect(properties).to.have.lengthOf(1); expect(properties[0].value).to.eql(value); +} + +function expectDropdownOptions(container, length, value) { + const selectOptions = domQuery('select', container).options; + + expect(selectOptions).to.have.lengthOf(length); + expect(selectOptions[0].value).to.eql(value); } \ No newline at end of file diff --git a/test/spec/cloud-element-templates/fixtures/condition-dropdown.json b/test/spec/cloud-element-templates/fixtures/condition-dropdown.json new file mode 100644 index 00000000..31bbcc68 --- /dev/null +++ b/test/spec/cloud-element-templates/fixtures/condition-dropdown.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "name": "Conditional dropdown", + "id": "example.com.dropdown-condition", + "description": "A conditional template.", + "appliesTo": ["bpmn:Task"], + "properties": [ + { + "id": "nameProp", + "label": "name", + "type": "String", + "binding": { + "type": "property", + "name": "name" + } + }, + { + "label": "dropdown", + "type": "Dropdown", + "value": "foo", + "choices": [ + { + "name": "FOO", + "value": "foo", + "condition": { + "property": "nameProp", + "equals": "foo" + } + }, + { + "name": "BAR", + "value": "bar", + "condition": { + "property": "nameProp", + "equals": "bar" + } + }, + { "name": "FOOBAR", "value": "foobar" } + ], + "binding": { + "type": "property", + "name": "customDropdownValue" + } + } + ] +}