How to clear extensions when I change Task type?


#1

Hi, everybody. I’m continuing to explore bpmn.io and I got stuck in this little problem regarding ExtensionElements that get created via bpmn-js-properties-panel.

The problem doesn’t show up when creating, modifying or deleting an extension. Everything is working fine. Except when whoever is using this model decides to change the type of a task that includes an extension.

I’ll explain myself better. I created this simple model:
before
The properties panel contains properties and attributes of the selected user task (that grey area covers some personal info), and I give to user the chance to add some custom extensions. Doing that, the XML generated looks like this:

...
<bpmn2:userTask id="_manual_task" name="This is a manual task">
  <bpmn2:extensionElements>
     <dm:priority code="2" />
     <dm:category code="Category02" />
   </bpmn2:extensionElements>
   ...
</bpmn2:userTask>
...

So far, so good. Let’s imagine that I made a mistake, that should be a Manual Task (as Id and Name properties shows), so: right click with my mouse, click on wrench, select manual task. My bpmn looks like this:
after
While my XML looks like this:

...
<bpmn2:manualTask id="_manual_task" name="This is a manual task">
  <bpmn2:extensionElements>
    <dm:priority code="2" />
    <dm:category code="Category02" />
  </bpmn2:extensionElements>
  ...
</bpmn2:manualTask>
...

And this where I notice for this first time that a change of task do not clean up existing extensions. Priority and Category are not selectable in a manual Task so, in order to keep the code clean and avoid problems, I’ve to take them away.

Question: how can I do that?

I tried to find some solution by myself, especially with changedElement listener of eventBus, but that means that I risk to clean up extensions at any editing action. Does anybody has a suggestion for me? Is there something missing or a workaround I can use?

Thanks in advance!


#2

Have a look at the ModelCloneHelper. Before cloning a model property the event bus will fire an event that you can listen for.

eventBus.on('property.clone', ({
  newElement,
  refTopLevelProperty,
  propertyDescriptor
}) => {
  if (newElement.$type !== 'myCustomTaskType' &&
      refTopLevelProperty.$type === 'bpmn:ExtensionElements') {
    
    // disallow copying extension elements
    return false;
  }
});

#3

Hi @philippfromme and thank you for your answer: this helped a little to navigate in depth on the eventBus world, but I might need your help again.

I used the approach you suggested but, unfortunately is not working because the ModelCloneHelper proceed on cloning the property since the property has no meta in it, therefore the property allowedIn is false. Here’s the code to help you understand:

var canClone = eventBus.fire('property.clone', {
  newElement: context.newElement,
  refTopLevelProperty: context.refTopLevelProperty,
  propertyDescriptor: extProp
});

if (!canClone) {
// if can clone is 'undefined' or 'false'
// check for the meta information if it is allowed
  if (propertyElement.$type === 'bpmn:ExtensionElements' &&
    extProp.meta && extProp.meta.allowedIn &&
    !isAllowedIn(extProp, context.newElement.$type)) {
    return false;
  }
}

This makes me believe I might not used the right approach when I created the properties in my moddle. Should I have to set somewhere that the isAllowedIn property should be set to true?


#4

You’re right, I’d consider this a bug. If the false is returned from firing the event it shouldn’t clone the property. I’ve created an issue for that: https://github.com/bpmn-io/bpmn-js/issues/888 Currently the only way to prevent cloning is to specify the allowedIn property.


#5

Thank you again, @philippfromme, I’ll follow the updates on github about it.

Btw, how can I set allowedIn property?
(is there any documentation/example I might look to better understand its use?)