Appearance
BPMN Allowed Items Processing
This document explains how toolbar items from panel.graph.toolbar.items are processed and converted to @mes/bpmn configuration.
Overview
The mapToolbarItem function in use-bpmn-widget-config.ts converts toolbar items into AllowedEntry objects that @mes/bpmn understands. This conversion process handles three types of toolbar items:
- String shortcuts - Simple strings like
"startEvent"and"endEvent" - ToolbarNodeItem objects - Event-driven node creation configuration and card metadata
- ToolbarEdgeItem objects - Full edge configurations with backend request details
Processing Logic
1. String Shortcuts for Start/End Events
typescript
if (typeof item === 'string') {
if (item === BPMN_NODE_KINDS.START_EVENT || item === BPMN_NODE_KINDS.END_EVENT) {
return item as AllowedEntry;
}
return undefined;
}Supported values:
"startEvent"→ Passed directly to@mes/bpmnas"startEvent""endEvent"→ Passed directly to@mes/bpmnas"endEvent"
Why these are special: Start and end events are built into @mes/bpmn and don't require additional configuration. The string is passed through unchanged to the widget.
2. Object Shortcuts for Start/End Events
typescript
if (
typeof item === 'object' &&
'bpmnType' in item &&
(item.bpmnType === BPMN_NODE_KINDS.START_EVENT || item.bpmnType === BPMN_NODE_KINDS.END_EVENT)
) {
return item.bpmnType as AllowedEntry;
}Example:
json
{
"bpmnType": "startEvent",
"icon": "pi pi-play"
}Conversion: The object is converted to the string "startEvent" before passing to @mes/bpmn. This allows you to:
- Keep one config format for all toolbar items (
events, ids, metadata) - Execute the same
onObjectCreatepipeline as tasks - Preserve compatibility with
@mes/bpmnbasic start/end entries
Important: Only bpmnType is sent to @mes/bpmn as palette entry. Other properties (events, ids, custom metadata) are still used in panel-side creation handling.
3. ToolbarNodeItem Processing
For full node configurations, the function:
- Finds the corresponding node config by:
typeName(preferred)- fallback by
bpmnType
- Extracts card fields from
nodeConfig.card.fields - Builds field attributes and labels for the creation form
- Adds
_bpmnTaskIdto emitted node data for toolbar matching - Constructs an AllowedEntry with:
kind: 'task'id- Toolbar item identifierfieldAttrs- Array of field keys for the cardlabels- Map of field keys to display labelsdata- Custom data merged with_bpmnTaskIdsize- Optional size override for created nodes
Important: _bpmnTaskId is used by request-create-nodes.ts to match created nodes back to the exact toolbar item and execute onObjectCreate actions.
Example conversion:
json
// Input (ToolbarNodeItem)
{
"id": "task-WorkOrderOperation",
"bpmnType": "task",
"typeName": "WorkOrderOperation",
"placeholderCard": { "title": "New Instruction" },
"events": [{
"name": "onObjectCreate",
"actions": [{ "name": "create", "editor": { "mode": "direct-request" } }]
}]
}
// Output (AllowedEntry passed to @mes/bpmn)
{
"kind": "task",
"id": "task-WorkOrderOperation",
"fieldAttrs": ["itemId", "name"],
"labels": { "itemId": "ID", "name": "Name" },
"data": {
"_bpmnTaskId": "task-WorkOrderOperation"
}
}Node data after creation in BPMN canvas:
json
{
"id": "Activity_abc123", // Generated by BPMN library
"type": "task",
"data": {
"_bpmnTaskId": "task-WorkOrderOperation"
}
}4. ToolbarEdgeItem Processing
For edge configurations, the function:
- Extracts the
request.linkName- This is REQUIRED for backend edge creation - Merges user-provided
datawith the request configuration - Constructs an AllowedEntry with:
kind: 'connector'bpmnType- BPMN edge type (e.g.,"bpmn:SequenceFlow")data.request.linkName- Backend link entity name- Additional
datafields for theme resolution
Example conversion:
json
// Input (ToolbarEdgeItem)
{
"id": "connection-critical",
"bpmnType": "bpmn:SequenceFlow",
"request": { "linkName": "WFConnectorInstance" },
"data": { "connectorType": "critical" }
}
// Output (AllowedEntry passed to @mes/bpmn)
{
"kind": "connector",
"id": "connection-critical",
"bpmnType": "bpmn:SequenceFlow",
"data": {
"connectorType": "critical",
"request": { "linkName": "WFConnectorInstance" }
}
}Data Flow Summary
Configuration to Widget
panel.graph.toolbar.items
↓
mapToolbarItem() for each item
↓ (adds _bpmnTaskId to emitted palette node data)
AllowedEntry[] array
↓
WidgetConfig.palette.allowed
↓
@mes/bpmn widgetNode Creation to Object Creation
1. User drags toolbar item to canvas
↓
2. @mes/bpmn creates node with data._bpmnTaskId
↓
3. bpmn:changed event fired
↓
4. processBpmnChanges() detects new node
↓
5. requestCreateNodes() called with node
↓
6. Matches toolbar item by: item.id === node.data._bpmnTaskId
↓
7. Executes toolbar item's `onObjectCreate` actions
↓
8. If action editor mode is `direct-request`, creation runs without modal
↓
9. Object/method request is executed and graph is refetchedImportant Notes
Start/End Event Conversion
We allow toolbar items to specify start and end events as objects (with bpmnType property), but we convert them to strings before passing to @mes/bpmn:
typescript
// Both of these inputs:
"startEvent"
{ "bpmnType": "startEvent", "events": [...] }
// Result in this @mes/bpmn config:
"startEvent"This design:
- Maintains flexibility - Users can specify
onObjectCreateactions for start/end events - Preserves @mes/bpmn API - The widget still receives simple strings
- Keeps creation behavior consistent - start/end and task use the same event pipeline
Creation Request Data
For ToolbarNodeItem, creation is configured via panel.graph.toolbar.items[].events[].actions[] (usually onObjectCreate). This is separate from node display configuration in panel.graph.nodes[].
For ToolbarEdgeItem, we use panel.graph.toolbar.items[].request.linkName directly. The linkName is embedded in the data.request object passed to @mes/bpmn.
Field Resolution Priority
When determining which fields to show on a node card:
- Primary source:
nodeConfig.card.fields(node configuration fromgraph.nodes[]) - Placeholder scope:
item.placeholderCard.titleonly (title override) - Fallback: Empty field array
This keeps placeholder behavior minimal and predictable while preserving field layout from node card configuration.