Appearance
BPMN
Purpose
Use a bpmn panel to load a backend workflow graph, map Object resources to BPMN nodes, and optionally create, edit, move, connect, or delete workflow elements.
When to use
Choose BPMN for a graph whose Object and Link resources are stored by the backend and whose lifecycle is persisted through object, link, or method actions. It is not a generic static diagram or a client-only BPMN editor.
Prerequisites and ownership
request.parentandrequest.methodmust identify a method returning the graph-state response expected by the panel.- Supply
request.objects, or bindrequest.getSelectedObjectForEventId. graph.nodesmaps backend entity types to visual cards and node operations.- Toolbar entries configure creation. Existing Link resources come from backend data.
- The panel owns method execution, response mapping, CRUD orchestration, and viewbox memory. Installed
@mes/bpmn@0.8.0owns canvas rendering and palette interaction.
Configuration surfaces
request acquires the graph, graph.nodes maps existing Object resources, graph.toolbar configures creation and package tools, and graph.readOnly controls editing. graph.theme remains a declared limitation rather than a supported theme configuration surface.
Capability map
| Area | Supported behavior |
|---|---|
| Acquisition | Runs one method request with parent, method, resolved objects, and opaque params |
| Node mapping | Matches backend metaType.typeName; optional bpmnType overrides inference |
| Node kinds | Task, start/end event, exclusive gateway, and parallel gateway |
| Cards | Interpolated title/subtitle, icon/avatar adaptation, and single- or multi-column fields |
| Palette | Stable item IDs; task/event/gateway entries; connector entries with backend linkName and optional contextual source/target |
| Tools | Hand, optimize, and delete visibility forwarded to the installed package |
| Lifecycle | Toolbar onObjectCreate; configured existing-node update/delete; connector create/delete; saved-connector endpoints can be changed only by deleting and drawing a replacement; node-position persistence |
| Read-only | Disables editing when graph.readOnly is true |
| Viewbox | Saves and restores panel viewbox across widget remounts in the current session |
Behavioral model
- The panel resolves
objects: explicit request values first, then the selected Object event when the explicit array is empty. - It runs the method and flattens returned Object/Link resource blocks.
- Backend Object resources become BPMN nodes.
typeNameselects the card mapping;bpmnTypewins over name-based start/end/gateway inference. - Backend Link resources become sequence or conditional flows from Link data.
- User changes are diffed against the last model and dispatched to the configured creation/update/delete paths. If the user drags either end of a saved connector to another node, the panel discards the move. Delete the connector and draw its replacement instead.
Creation and display are intentionally separate: toolbar items say how to create, while graph.nodes says how existing entities render and edit.
Alternatives, defaults, and precedence
request.objectswins when non-empty; the selected event is the fallback.graph.readOnlydefaults tofalse.- Node kind: exact node mapping
bpmnType, then type-name inference, thentask. - Palette task title:
placeholderCard.title, matching node-card title,typeName, then toolbar itemid. - Installed package defaults show hand, optimize, and delete controls when the corresponding values are omitted.
- Created task size defaults in the installed package to
292 × 132; an explicit toolbarsizeoverrides it.
Limitations and declared/runtime drift
graph.edgesis not a supported configuration parameter. Older saved JSON configurations that still contain it remain loadable because the panel does not read the extra property. Remove it when editing a configuration; existing connectors continue to come from Link resources in the graph method response.graph.themeis declared but ignored; the adapter supplies its own theme.graph.toolbar.showConnectis forwarded by the adapter but ignored by the installed package.paramsis method-specific and intentionally typed as unknown.- The runnable local fixture is intentionally read-only. It does not prove any creation, update, deletion, or connector-persistence contract.
Contextual Link endpoints
By default, a new connector persists the GUID of each Object represented by a connected BPMN node as its sourceGuid or targetGuid. Configure getGraphContextLink on either endpoint when the saved connector must use the GUID of an existing Link between the current graph-request Object and the Object represented by that visual node.
The user only draws the connector. BPMN performs the contextual lookup automatically:
- BPMN reads the Object GUIDs supplied to the current graph request, after resolving
request.objectsorrequest.getSelectedObjectForEventId. It continues only when this input contains one GUID and uses that Object as the current graph-request Object. It does not derive this Object from the method response. - Connector creation triggers
POST /Object/getLinkedObjects. BPMN sends the current graph-request Object, the required technicalgetGraphContextLink.linkName, and the configured direction. - BPMN matches the response against the visual endpoint and accepts exactly one distinct
link.objectGuid. - Immediately before
POST /Link, BPMN verifies that the same graph-request Object is still current. It writes the accepted Link GUID to the configuredsourceGuidortargetGuid; an unconfigured endpoint keeps the GUID of the Object represented by the connected node. - BPMN reruns the graph acquisition method. The returned graph replaces the temporary connector on the canvas with the saved connector and its Link GUID.
No Tree or Table panel, linked-row selection, preload, or panelId is required.
This configuration contains every field needed to create a Link-to-Object connector. Replace these project-specific values before use:
FlowHead— the metatype with the graph acquisition method;getFlowGraph— the name of that MethodRun method;- the value in
request.objects— the one current graph-request Object GUID; FlowStatus— the technical type of the existing contextual Link;ContextualStatusTransition— the new connector type compatible with Link-to-Object endpoints.
This BPMN panel creates a Link-to-Object connector. The existing FlowStatus Link from the current graph-request Object to the Object represented by the visual source becomes the saved connector source:
json
{
"id": "flow-bpmn",
"type": "bpmn",
"request": {
"parent": "FlowHead",
"method": "getFlowGraph",
"objects": ["11111111-1111-1111-1111-111111111111"],
"params": {}
},
"graph": {
"readOnly": false,
"toolbar": {
"items": [
{
"id": "contextual-status-transition",
"bpmnType": "bpmn:SequenceFlow",
"request": {
"linkName": "ContextualStatusTransition",
"source": {
"getGraphContextLink": {
"linkName": "FlowStatus",
"reverse": false
}
}
}
}
]
},
"nodes": []
}
}getGraphContextLink.linkName is the technical type of the existing contextual Link. It is required and is usually different from the outer request.linkName, which names the new connector type.
reverse controls the direction of the Link that BPMN asks POST /Object/getLinkedObjects to find:
- omitted
reverse, orreverse: false: current graph-request Object → Object represented by the visual node; reverse: true: Object represented by the visual node → current graph-request Object.
The direction describes the existing contextual Link, not the visual direction of the new connector. Use the same getGraphContextLink object under request.target for Object-to-Link or Link-to-Link creation.
Use an event endpoint instead when the endpoint must come from a row the user explicitly selected, independently of the visual BPMN node. The referenced event must save its ObjectSelector through addSelectedObjectToRequest:
json
{
"source": {
"getSelectedObjectForEventId": "source-status--on-select"
},
"target": {
"getSelectedObjectForEventId": "target-status--on-select",
"idSource": "link"
}
}idSource: "link"resolves the selected Link GUID.- Omitted
idSource, oridSource: "linkedObject", resolves the selected object's GUID. getSelectedObjectForEventIdandgetGraphContextLinkare mutually exclusive for one endpoint. A mixed endpoint is rejected before any lookup.- Omit
sourceortargetto keep the GUID of the Object represented by the connected BPMN node for that endpoint. getGraphContextLink.linkNamemust be a non-empty technical Link type.- Missing, ambiguous, malformed, or incomplete linked-object results are unresolved. A graph-context change during lookup is unresolved as well. BPMN does not fall back to the Object represented by the node and does not create the connector.
- The outer
request.linkNamemust identify a Link type compatible with the resolved Object/Link endpoint kinds. For example, an Object-to-Object type cannot create Link-to-Object.
If no connector remains after drawing
BPMN does not send POST /Link when it cannot safely determine the Link GUID for the configured endpoint. The panel shows the reason in a notification, obtains the graph again, and removes the unsaved connector. Read the notification first, then follow the matching action:
- Exactly one current graph Object is required. Put one GUID in
request.objects, or configurerequest.getSelectedObjectForEventIdto supply one GUID before the graph method runs. The panel validates this input automatically; you do not validate the method response. If the workflow intentionally has zero or several context Objects,getGraphContextLinkdoes not fit: omitsourceortargetfor an Object endpoint, or configure explicit Link selection through an event andidSource: "link". - No Link was found. Check three values: the technical type in
getGraphContextLink.linkName, the direction inreverse, and the Object GUID supplied to the graph request. Withreverse: false, the existing Link must run from that Object to the Object represented by the visual node; withreverse: true, it must run in the opposite direction. Retry only after correcting a value or creating the missing Link in the application interface that edits relationships between Objects. If the endpoint should store an Object GUID, omitsourceortargetand use a compatible new Link type. - Multiple Links were found. Automatic lookup cannot choose one. Remove invalid duplicates in the relationship-editing interface. If every Link is valid, configure the explicit selection shown above with
getSelectedObjectForEventIdandidSource: "link". - The graph is loading or its Object changed. Wait for the current graph and draw the connector again. BPMN does not use a result from the previous context.
- The API request failed or its response was invalid. Wait for the current graph and retry once. If the error repeats, include the notification text,
getGraphContextLink.linkName,getGraphContextLink.reverse, graph-request Object GUID, and connected node GUID in the issue report. This endpoint strategy cannot be used until the API response is corrected.
If relationship editing is unavailable, do not keep drawing after a missing or ambiguous Link notification. Include the notification text, getGraphContextLink.linkName, getGraphContextLink.reverse, graph-request Object GUID, and connected node GUID in the issue report.
Drawing again without changing the configuration, data, or API state produces the same result. Connector creation does not create a missing Link or remove duplicates automatically.
After a POST /Link, the server must return one UUID for each requested Link. BPMN then runs the graph method again and shows success only when the returned graph contains every UUID from the creation response.
- If the notification says that a Link was created but its connector did not appear, the Link already exists. The widget reports its GUID. Do not draw the connector again. Check the Link by GUID in the relationship-editing interface or attach the GUID and notification text to an issue report.
- If the notification says that BPMN could not determine whether the Link was created, do not draw the connector again until you check both the connector between the source and target nodes and the expected Link in the relationship-editing interface. If that check is unavailable, attach the notification text and the complete
requestblock from the panel configuration; it showsrequest.linkNameand whether the optionalrequest.sourceandrequest.targetfields are present or absent.
The graph acquisition method or its script remains responsible for mapping the saved contextual Link back to visual source and target node IDs. The user cannot move the beginning or end of any saved connector to another node, regardless of the current toolbar configuration. If the user tries, BPMN does not send PUT /Link; it runs the configured graph method again, so the connector returns to its previous position. To change the connection, delete the connector and draw a new one. This restriction applies because the graph response provides enough data to display an edge, but not enough source data to determine whether its saved endpoints are Object GUIDs or Link GUIDs.
Deleting an existing connector is unchanged. BPMN deletes it by the persisted connector Link GUID returned by the graph method; getGraphContextLink is not run during deletion.
Minimal configuration
json
{
"id": "workflow",
"type": "bpmn",
"request": {
"parent": "WFEntityInstance",
"method": "getWorkFlowGraphState",
"objects": [],
"params": {}
},
"graph": {
"readOnly": true,
"toolbar": { "items": [] },
"nodes": []
}
}Scenario: editable workflow tasks and connectors
json
{
"id": "work-order-workflow",
"type": "bpmn",
"request": {
"parent": "WFEntityInstance",
"method": "getWorkFlowGraphState",
"objects": [],
"params": {},
"getSelectedObjectForEventId": "work-orders--selected"
},
"graph": {
"readOnly": false,
"toolbar": {
"items": [
{
"id": "task-operation",
"bpmnType": "task",
"typeName": "WorkOrderOperation",
"icon": "icon icon--task",
"size": { "w": 292, "h": 132 },
"placeholderCard": { "title": "New operation" },
"events": [
{
"id": "workflow--create-operation",
"name": "onObjectCreate",
"actions": [
{
"name": "create",
"editor": {
"mode": "modal",
"entityType": {
"object": { "metaTypeName": "WorkOrderOperation" }
},
"fields": [
{ "attribute": "itemId", "label": "Number" },
{ "attribute": "name", "label": "Name" }
]
}
}
]
}
]
},
{
"id": "workflow-link",
"bpmnType": "bpmn:SequenceFlow",
"icon": "icon icon--arrow",
"request": { "linkName": "WFConnectorInstance" }
}
],
"showHand": true,
"showOptimize": true,
"showDelete": true
},
"nodes": [
{
"typeName": "WorkOrderOperation",
"bpmnType": "task",
"card": {
"title": "{{name}}",
"subtitle": "{{itemId}}",
"icon": "clock-settings",
"fields": [
{ "key": "state", "label": "State" },
[
{ "key": "created_at", "label": "Created" },
{ "key": "modified_at", "label": "Modified" }
]
]
},
"events": []
}
]
}
}Expected result: selecting a work order runs the graph method, mapped operations render as cards, and the palette can start the configured creation/link flows. Add exact update/delete events only after their backend action contracts are verified.
Runnable demos
Open the shared configuration journeysOpen the BPMN tab. The panel sends parent, method, one Object GUID, and non-empty params through the real POST /MetaMethods/Run route. The local handler returns the adapter's triple-nested response: three LocalObject nodes (start, task, end) and two backend Link resources. The configured graph.nodes entries map each backend typeName to its BPMN kind and interpolate card title, subtitle, and state.
The fixture sets graph.readOnly: true, supplies no palette entries, and hides delete. It is evidence only for graph acquisition, mapping, rendering, and read-only controls; it must not be cited as evidence for editable workflows.
Exact parameter reference
- Request:
parent,method,objects,params, selection event - Graph: read-only, toolbar items, ignored theme
- Toolbar objects: ID, icon, kind, backend type, events, width, height, data, placeholder, connector link, connector source, connector target, contextual Link type, contextual Link direction
- Toolbar controls: hand, optimize, delete, declared connect
- Existing nodes: type, kind, title, subtitle, field key, field label, icon, events
Related guides and next task
Next, copy the read-only acquisition and node mappings. Verify one real creation/persistence path before enabling edit, delete, or connector controls.