diff --git a/lib/camunda-cloud/VersionTagBehavior.js b/lib/camunda-cloud/VersionTagBehavior.js new file mode 100644 index 0000000..99993c6 --- /dev/null +++ b/lib/camunda-cloud/VersionTagBehavior.js @@ -0,0 +1,50 @@ +import { isDefined } from 'min-dash'; + +import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; + +import { isAny } from 'bpmn-js/lib/util/ModelUtil'; + +/** + * Zeebe BPMN specific version tag behavior. + */ +export default class VersionTagBehavior extends CommandInterceptor { + constructor(eventBus) { + super(eventBus); + + /** + * Ensure that `zeebe:BindingTypeSupported` (`zeebe:CalledDecision`, + * `zeebe:CalledElement` and `zeebe:FormDefinition`) only has + * `zeebe:versionTag` if `zeebe:bindingType` is `versionTag`. + */ + this.preExecute('element.updateModdleProperties', function(context) { + const { + moddleElement, + properties + } = context; + + if (!isAny(moddleElement, [ + 'zeebe:CalledDecision', + 'zeebe:CalledElement', + 'zeebe:FormDefinition' + ])) { + return; + } + + // unset `zeebe:versionTag` if `zeebe:bindingType` is not set to `versionTag` + if ('bindingType' in properties + && properties.bindingType !== 'versionTag' + && isDefined(moddleElement.get('versionTag'))) { + properties.versionTag = undefined; + } + + // set `zeebe:bindingType` to `versionTag` if `zeebe:versionTag` is set + if ('versionTag' in properties && moddleElement.get('bindingType') !== 'versionTag') { + properties.bindingType = 'versionTag'; + } + }, true); + } +} + +VersionTagBehavior.$inject = [ + 'eventBus' +]; \ No newline at end of file diff --git a/lib/camunda-cloud/index.js b/lib/camunda-cloud/index.js index 2aa6779..ae2c534 100644 --- a/lib/camunda-cloud/index.js +++ b/lib/camunda-cloud/index.js @@ -9,6 +9,7 @@ import DeleteParticipantBehaviour from '../shared/DeleteParticipantBehaviour'; import FormsBehavior from './FormsBehavior'; import RemoveAssignmentDefinitionBehavior from './RemoveAssignmentDefinitionBehavior'; import RemoveTaskScheduleBehavior from './RemoveTaskScheduleBehavior'; +import VersionTagBehavior from './VersionTagBehavior'; export default { __init__: [ @@ -22,7 +23,8 @@ export default { 'deleteParticipantBehaviour', 'formsBehavior', 'removeAssignmentDefinitionBehavior', - 'removeTaskScheduleBehavior' + 'removeTaskScheduleBehavior', + 'versionTagBehavior' ], cleanUpBusinessRuleTaskBehavior: [ 'type', CleanUpBusinessRuleTaskBehavior ], cleanUpEndEventBehavior: [ 'type', CleanUpEndEventBehavior ], @@ -34,5 +36,6 @@ export default { deleteParticipantBehaviour: [ 'type', DeleteParticipantBehaviour ], formsBehavior: [ 'type', FormsBehavior ], removeAssignmentDefinitionBehavior: [ 'type', RemoveAssignmentDefinitionBehavior ], - removeTaskScheduleBehavior: [ 'type', RemoveTaskScheduleBehavior ] + removeTaskScheduleBehavior: [ 'type', RemoveTaskScheduleBehavior ], + versionTagBehavior: [ 'type', VersionTagBehavior ] }; diff --git a/test/camunda-cloud/VersionTagBehaviorSpec.js b/test/camunda-cloud/VersionTagBehaviorSpec.js new file mode 100644 index 0000000..ef16861 --- /dev/null +++ b/test/camunda-cloud/VersionTagBehaviorSpec.js @@ -0,0 +1,94 @@ +import { + bootstrapCamundaCloudModeler, + inject +} from 'test/TestHelper'; + +import { + getBusinessObject, + isAny +} from 'bpmn-js/lib/util/ModelUtil'; + +import diagramXML from './version-tag.bpmn'; + + +describe('camunda-cloud/features/modeling - VersionTagBehavior', function() { + + beforeEach(bootstrapCamundaCloudModeler(diagramXML)); + + + [ + 'CallActivity', + 'BusinessRuleTask', + 'UserTask' + ].forEach(function(type) { + + describe('unset version tag', function() { + + it('should unset version tag', inject(function(elementRegistry, modeling) { + + // given + const element = elementRegistry.get(`${ type }_1`); + + const extensionElement = getExtensionElement(element); + + expect(extensionElement.get('bindingType')).to.equal('versionTag'); + expect(extensionElement.get('versionTag')).to.equal('v1.0.0'); + + // when + modeling.updateModdleProperties(element, extensionElement, { + bindingType: 'deployment' + }); + + // then + expect(extensionElement.get('bindingType')).to.equal('deployment'); + expect(extensionElement.get('versionTag')).not.to.exist; + })); + + }); + + describe('set binding type', function() { + + it('should set binding type', inject(function(elementRegistry, modeling) { + + // given + const element = elementRegistry.get(`${ type }_2`); + + const extensionElement = getExtensionElement(element); + + expect(extensionElement.get('bindingType')).to.equal('deployment'); + + // when + modeling.updateModdleProperties(element, extensionElement, { + versionTag: 'v1.0.0' + }); + + // then + expect(extensionElement.get('bindingType')).to.equal('versionTag'); + expect(extensionElement.get('versionTag')).to.equal('v1.0.0'); + })); + + }); + + }); + +}); + +// helpers ////////// + +function getExtensionElement(element) { + const businessObject = getBusinessObject(element); + + const extensionElements = businessObject.get('extensionElements'); + + if (!extensionElements) { + return null; + } + + return extensionElements.get('values').find(extensionElement => { + return isAny(extensionElement, [ + 'zeebe:CalledDecision', + 'zeebe:CalledElement', + 'zeebe:FormDefinition' + ]); + }); +} \ No newline at end of file diff --git a/test/camunda-cloud/version-tag.bpmn b/test/camunda-cloud/version-tag.bpmn new file mode 100644 index 0000000..dca9dce --- /dev/null +++ b/test/camunda-cloud/version-tag.bpmn @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +