Custom Menu Provider (extends ReplaceMenuProvider)


#1

I’m trying with creating a custom task (custom task of type service task) in the sub menu. With the reference to the articles (ref1, ref2), the source code should be changed in-order to add or remove the menu items.

Is it true or the ReplaceMenuProvider can be extended and pass the override items when create instance of Bpmn. Attached sample code below.

Code:

loadModeler() {
    this.container = document.getElementById('js-drop-zone');
    this.modeler = new BpmnJS({
      container: '#js-canvas',
      propertiesPanel: {
        parent: '#js-properties-panel'
      },
      additionalModules: [
        propertiesPanelModule,
        propertiesProviderModule
      ],
      replaceMenuProvider: [], // <-- something like this.
      moddleExtensions: {
        camunda: camundaModdleDescriptor,
        qa: qaPackage
      }
    });

#2

You’d override the provider like any other module:

const modeler = new BpmnJS({
  additionalModules: [
     myReplaceMenuProvider
  ]
});

Make sure the provider module has the same name in order to override.

export default {
  __depends__: [
    PopupMenuModule,
    ReplaceModule
  ],
  __init__: [ 'replaceMenuProvider' ],
  replaceMenuProvider: [ 'type', MyReplaceMenuProvider ]
};

#3

I’ve tried to directly use the ReplaceMenuProvider in additoinalModules by modify TASK name from ReplaceOptions. But it didn’t work out. Is there anything else should be done.?

import * as CustomMenuProvider from 'bpmn-js/lib/features/popup-menu/ReplaceMenuProvider'

 loadModeler() {
    this.container = document.getElementById('js-drop-zone');
    this.modeler = new BpmnJS({
      container: '#js-canvas',
      keyboard: { bindTo: document },
      propertiesPanel: {
        parent: '#js-properties-panel'
      },
      additionalModules: [
        propertiesPanelModule,
        propertiesProviderModule,
        CustomMenuProvider, // <-- used the default provider. Just modified the TASK name from ReplaceOptions
      ],
      replaceMenuProvider: [],
      moddleExtensions: {
        camunda: camundaModdleDescriptor,
      }
    });

ReplaceOptions:

// modified task label and added SMS Task
export var TASK = [
  {
    label: 'Task - CUSTOM',
    actionName: 'replace-with-task',
    className: 'bpmn-icon-task',
    target: {
      type: 'bpmn:Task'
    }
  },{
    label: 'SMS Task',
    actionName: 'replace-with-sms-subprocess',
    className: 'bpmn-icon-send',
    target: {
      type: 'bpmn:Task'
    }
  }

Expecting the above items will reflect in sub-menu.


#4

It’s hard to guess what the issue is. Overriding components should be straight forward. You may have a look at the custom elements example where we make heavy use of overriding components.


#5

How to do
CustomReplaceMenuProvider

import inherits from 'inherits';
import ReplaceMenuProvider from 'bpmn-js/lib/features/popup-menu';
export default function CustomReplaceMenuProvider() {
  debugger;
  ReplaceMenuProvider.call(this);
  console.log("replaceOptions:", this.replaceOptions);
}
inherits(CustomReplaceMenuProvider, ReplaceMenuProvider);
CustomReplaceMenuProvider.$inject = ['popupMenu', 'modeling', 'moddle',
  'bpmnReplace', 'rules', 'translate'
];

zone.js:2198 Uncaught TypeError: Object prototype may only be an Object or null: undefined
at create ()
at Function.Object.create (zone.js:2198)
at inherits (inherits_browser.js:5)
at Module…/src/app/bpmn-js/awtCustom/CustomReplaceMenuProvider.js (CustomReplaceMenuProvider.js:8)
at webpack_require (bootstrap:78)
at Module…/src/app/bpmn-js/awtCustom/index.js (index.js:1)
at webpack_require (bootstrap:78)
at Module…/src/app/bpmn-js/bpmn-js.ts (bpmn-js.ts:1)
at webpack_require (bootstrap:78)
at Module…/src/app/flow/bpmn/bpmn.component.ts (main.js:1860)


#6

What are you trying to do?


#7

in debugger error next line
Uncaught TypeError:

I try to append new task in menu like it.
1

import inherits from 'inherits';

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

import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer';
import BpmnRenderer from 'bpmn-js/lib/draw/BpmnRenderer';
import {
  isExpanded,
  isEventSubProcess
}
from 'bpmn-js/lib/util/DiUtil';

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

import {
  createLine
} from 'diagram-js/lib/util/RenderUtil';

import {
  isTypedEvent,
  isThrowEvent,
  isCollection,
  getDi,
  getSemantic,
  getCirclePath,
  getRoundRectPath,
  getDiamondPath,
  getRectPath,
  getFillColor,
  getStrokeColor
}
from 'bpmn-js/lib/draw/BpmnRenderUtil';

import {
  query as domQuery
} from 'min-dom';

import {
  append as svgAppend,
  attr as svgAttr,
  create as svgCreate,
  classes as svgClasses
} from 'tiny-svg';

import {
  rotate,
  transform,
  translate
} from 'diagram-js/lib/util/SvgTransformUtil';

import Ids from 'ids';

export default function CustomBpmnRenderer(config, eventBus, styles, pathMap,
  canvas, textRenderer) {
  BpmnRenderer.call(this, config, eventBus, styles, pathMap,
    canvas, textRenderer, 2000);
}
inherits(CustomBpmnRenderer, BpmnRenderer);
CustomBpmnRenderer.$inject = ['config', 'eventBus', 'styles', 'pathMap',
  'canvas', 'textRenderer'
];
CustomBpmnRenderer.prototype.drawShape = function (parentGfx, element) {
  var type = element.type;
  if (type === 'bpmn:Step1Task') {
    debugger;
  }
  var h = this.handlers[type];
  /* jshint -W040 */
  return h(parentGfx, element);
};


#8

Since I’ve read you other topic I assume you’re trying to replace an element with your bpmn:Step1. Where do you define this type of element?


#9

Yes same as How to New Task in taskList with task
I’m trying
https://github.com/bpmn-io/bpmn-js-custom-elements-example

THX


#10

Can you please prepare a repository with your code? It looks like the modeler on screenshots is not built upon the emoji custom elements repository.