Skip to content

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.parent and request.method must identify a method returning the graph-state response expected by the panel.
  • Supply request.objects, or bind request.getSelectedObjectForEventId.
  • graph.nodes maps 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.0 owns 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 ​

AreaSupported behavior
AcquisitionRuns one method request with parent, method, resolved objects, and opaque params
Node mappingMatches backend metaType.typeName; optional bpmnType overrides inference
Node kindsTask, start/end event, exclusive gateway, and parallel gateway
CardsInterpolated title/subtitle, icon/avatar adaptation, and single- or multi-column fields
PaletteStable item IDs; task/event/gateway entries; connector entries with backend linkName and optional contextual source/target
ToolsHand, optimize, and delete visibility forwarded to the installed package
LifecycleToolbar 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-onlyDisables editing when graph.readOnly is true
ViewboxSaves and restores panel viewbox across widget remounts in the current session

Behavioral model ​

  1. The panel resolves objects: explicit request values first, then the selected Object event when the explicit array is empty.
  2. It runs the method and flattens returned Object/Link resource blocks.
  3. Backend Object resources become BPMN nodes. typeName selects the card mapping; bpmnType wins over name-based start/end/gateway inference.
  4. Backend Link resources become sequence or conditional flows from Link data.
  5. 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.objects wins when non-empty; the selected event is the fallback.
  • graph.readOnly defaults to false.
  • Node kind: exact node mapping bpmnType, then type-name inference, then task.
  • Palette task title: placeholderCard.title, matching node-card title, typeName, then toolbar item id.
  • 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 toolbar size overrides it.

Limitations and declared/runtime drift ​

  • graph.edges is 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.theme is declared but ignored; the adapter supplies its own theme.
  • graph.toolbar.showConnect is forwarded by the adapter but ignored by the installed package.
  • params is 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.

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:

  1. BPMN reads the Object GUIDs supplied to the current graph request, after resolving request.objects or request.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.
  2. Connector creation triggers POST /Object/getLinkedObjects. BPMN sends the current graph-request Object, the required technical getGraphContextLink.linkName, and the configured direction.
  3. BPMN matches the response against the visual endpoint and accepts exactly one distinct link.objectGuid.
  4. Immediately before POST /Link, BPMN verifies that the same graph-request Object is still current. It writes the accepted Link GUID to the configured sourceGuid or targetGuid; an unconfigured endpoint keeps the GUID of the Object represented by the connected node.
  5. 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, or reverse: 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, or idSource: "linkedObject", resolves the selected object's GUID.
  • getSelectedObjectForEventId and getGraphContextLink are mutually exclusive for one endpoint. A mixed endpoint is rejected before any lookup.
  • Omit source or target to keep the GUID of the Object represented by the connected BPMN node for that endpoint.
  • getGraphContextLink.linkName must 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.linkName must 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:

  1. Exactly one current graph Object is required. Put one GUID in request.objects, or configure request.getSelectedObjectForEventId to 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, getGraphContextLink does not fit: omit source or target for an Object endpoint, or configure explicit Link selection through an event and idSource: "link".
  2. No Link was found. Check three values: the technical type in getGraphContextLink.linkName, the direction in reverse, and the Object GUID supplied to the graph request. With reverse: false, the existing Link must run from that Object to the Object represented by the visual node; with reverse: 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, omit source or target and use a compatible new Link type.
  3. 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 getSelectedObjectForEventId and idSource: "link".
  4. 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.
  5. 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 request block from the panel configuration; it shows request.linkName and whether the optional request.source and request.target fields 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 journeys

Open 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 ​

Next, copy the read-only acquisition and node mappings. Verify one real creation/persistence path before enabling edit, delete, or connector controls.