How to remove Elements from ContextPad

Hello,
I would like to remove some elements which are shown in the contextPad. Since there is only 1 Element from which I want to manipulate its contextPad, I don‘t want to override the whole contextPadProvider. Is there an easier method of how to do it?

Yes this is possible. Your custom provider can return a function which will then be able to adjust the current entries, so also deleting elements of entries is possible.

I tried to remove the items, which I have rounded red in the Screenshot.
image
For that I have written the following Code:

import {
  is
} from 'bpmn-js/lib/util/ModelUtil';

import {
  assign,
  forEach,
  isArray
} from 'min-dash';

export default class CustomContextPad {
  constructor(config, contextPad, create, elementFactory, injector, translate) {
    this.create = create;
    this.elementFactory = elementFactory;
    this.translate = translate;

    if (config.autoPlace !== false) {
      this.autoPlace = injector.get('autoPlace', false);
    }

    contextPad.registerProvider(this);
  }

  getContextPadEntries(element) {
    const {
      autoPlace,
      create,
      elementFactory,
      translate
    } = this;
	
	var actions = {};
	var businessObject = element.businessObject;

    function appendServiceTask(event, element) {
    //  if (autoPlace) {
        const shape = elementFactory.createShape({ type: 'bpmn:Transaction' });
  
    //    autoPlace.append(element, shape);
   //   } else {
        appendServiceTaskStart(event, element);
    //  }
    }

    function appendServiceTaskStart(event) {
      const shape = elementFactory.createShape({ type: 'bpmn:Transaction' });
      create.start(event, shape, element);
    }
	function TaskStart(event) {
      const shape = elementFactory.createShape({ type: 'bpmn:Task' });
      create.start(event, shape, element);
    }
	if (is(businessObject, 'bpmn:Transaction') || is(businessObject, 'bpmn:Task')) {
		assign(actions, {
		'append.Task': {
			group: 'artifact',
			className: 'bpmn-icon-task',
			title: translate('Append Task'),
			action: {
			click: TaskStart,
			dragstart: TaskStart
			}
		}
		}); 
		assign(actions, {
		'append.service-task': {
			group: 'artifact',
			className: 'bpmn-icon-transaction',
			title: translate('Append AssistanceSystem'),
			action: {
			click: appendServiceTask,
			dragstart: appendServiceTaskStart
			}
		}
		});
	}
	return actions;
  }
}

CustomContextPad.$inject = [
  'config',
  'contextPad',
  'create',
  'elementFactory',
  'injector',
  'translate'
];

Why does that not work or what I am doing wrong respectively?

I do not see in your code snippet where you remove these items. You are creating a new context pad provider with additional items. Furthermore, it seems like (according to the screenshot) you include your custom and the default context pad provider into your application.

What’s the module name of your custom context pad provider and how do you integrating it? Make sure you’re overriding the existing contextPadProvider module if you’re going this route or try the function-wise approach which I linked above.

I actually thought, I would already override the Default context pad by the custom context pad.
I integrated this through an index.js - file like this:

import CustomContextPad from './CustomContextPad';
import CustomPalette from './CustomPalette';
import CustomRenderer from './CustomRenderer';
import CustomRules from './CustomRules';

export default {
  __init__: [ 'customContextPad', 'customPalette', 'customRenderer', 'customRules' ],
  customContextPad: [ 'type', CustomContextPad ],
  customPalette: [ 'type', CustomPalette ],
  customRenderer: [ 'type', CustomRenderer ],
  customRules: [ 'type', CustomRules ]
};

Could you explain, how I override the contextPadProvider correctly?

Please first you have to consider that there is a difference between the ContextPad and a ContextPadProvider. The ContextPad goes over all providers and fetches their entries.

What do you want to create is a ContextPadProvider, not a new context pad. There can be multiple providers.

Secondly, if you really want to override the existing ContextPadProvider, you have to use the exact name of this module, so contextPadProvider.

Nevertheless, to remove entries from the context pad, instead of overriding the existing provider, you can always delete existing entries by the function-method I linked above (where you can handle the already registered entries).

I hope this clarifies a bit the difference between the actual context pad and its providers.

when I use the

return function(entries) {…}

method. How can I delete specific Elements from it? I can’t figure out which function I must use exactly.

This example is related to the replace menu, but it can easily mapped to the context pad provider.

So your getContextPadEntries can return a function like this

getContextPadEntries(element) {
  /* ... */

  return function(entries) {

    // entries includes all already registered context pad entries

    // remove end event option from entries, for example
   delete entries['append.end-event'];

   return entries;
  }
}

You can find all default entries here.

2 Likes

This example shows basically what you’re looking for: https://codesandbox.io/s/bpmn-js-custom-context-pad-provider-remove-entry-t7vnz

Thank you very much. I was now able to find a working solution.