Properties panel extension - extend getTabs


#1

Good morning,
I’m trying to get experience in writing plugins for Camunda Modeler, and I am trying to extend the properties panel like the bpmn-js example here.
I managed to create this plugin following the example, to create a ‘General’ tab for every element and also a ‘Magic’ tab for the StartEvent, but what I would like to do now is to get the previous ‘propertiesProvider’ and extend its getTabs property appending the Magic tab.
I tried different solutions without success. It returns me the error ‘Cannot resolve circular dependency! (Resolving: propertiesPanel -> propertiesProvider -> propertiesProvider)’ . What’s wrong?

function SharedPropertiesProvider(eventBus, propsProvider, elementRegistry) {
  PropertiesActivator.call(this, eventBus);
  var oldProvider = propsProvider;

  this.getTabs = (element) => {
    // The "magic" tab
    var magicTab = {
      id: 'magic',
      label: 'Magic',
      groups: createMagicTabGroups(element, elementRegistry)
    };
      var oldGetTabs = oldProvider.getTabs(element);
      oldGetTabs.push(magicTab);
      return oldGetTabs;
  };
}

inherits(SharedPropertiesProvider, PropertiesActivator);

SharedPropertiesProvider.$inject = [ 
    'eventBus', 'propertiesProvider', 'elementRegistry'
];

module.exports = {
  __init__: [ 'propertiesProvider' ],
  propertiesProvider: [ 'type', SharedPropertiesProvider ]
};

#2

Finally found a solution for the problem, getting CamundaPropertiesProvider did the trick:

function SharedPropertiesProvider(eventBus, bpmnFactory, elementRegistry, elementTemplates, translate) {
      PropertiesActivator.call(this, eventBus);
      var camunda = new CamundaPropertiesProvider(eventBus, bpmnFactory, elementRegistry, elementTemplates, translate);
      this.getTabs = function(element) {
           // The "magic" tab
           var magicTab = {
           id: 'magic',
           label: 'Magic',
           groups: createMagicTabGroups(element, elementRegistry)
       };

       var array = camunda.getTabs(element);
       array.push(magicTab);
       return array;
}

Now I just have to figure out how to inject the ‘magic moddle’ to BpmnModeler.


#3

My solution was that I wasn’t injecting parameters to the provider:

MagicPropertiesProvider.$inject = [
‘eventBus’,
‘bpmnFactory’,
‘elementRegistry’,
‘translate’
];


#4

I finally found a more reliable solution to my first question, avoiding circular dependency. It’s better to explain it using the first example. Instead of instantiating a new CamundaPropertiesProvider, I use again the propertiesProvider injected and extend it. I don’t know why I did not think about it earlier.

function SharedPropertiesProvider(eventBus, propertiesProvider, elementRegistry) {
  PropertiesActivator.call(this, eventBus);

let oldProviderGetTabs = propertiesProvider.getTabs;

  propertiesProvider.getTabs = (element) => {
    // The "magic" tab
    var magicTab = {
      id: 'magic',
      label: 'Magic',
      groups: createMagicTabGroups(element, elementRegistry)
    };
      var arrayTabs = oldProviderGetTabs(element);
      arrayTabs.push(magicTab);
      return arrayTabs ;
  };
}

inherits(SharedPropertiesProvider, PropertiesActivator);

SharedPropertiesProvider.$inject = [ 
    'eventBus', 'propertiesProvider', 'elementRegistry'
];

module.exports = {
  __init__: [ 'magicPropertiesProvider' ], // MUST BE A DIFFERENT NAME!!!
  magicPropertiesProvider: [ 'type', SharedPropertiesProvider ]
};

In this way, you get the old instance of the propertiesProvider (camundaPropertiesProvider, or even another extended one in this way) and you extend it adding groups to the previous array result.
I feel better now.