Skip to content

BPMN

Purpose

Use a bpmn panel to load a backend workflow graph, map backend objects to BPMN nodes, and optionally create, edit, move, connect, or delete workflow elements.

When to use

Choose BPMN for a graph whose nodes and links are backend entities 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 links come from backend data.
  • The panel owns method execution, response mapping, CRUD orchestration, and viewbox memory. Installed @mes/bpmn@0.7.1 owns canvas rendering and palette interaction.

Configuration surfaces

request acquires the graph, graph.nodes maps existing objects, graph.toolbar configures creation and package tools, and graph.readOnly controls editing. The declared graph.edges and graph.theme surfaces are limitations rather than supported existing-edge/theme configuration.

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
ToolsHand, optimize, and delete visibility forwarded to the installed package
LifecycleToolbar onObjectCreate; configured existing-node update/delete; connector create/update/delete; 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 blocks.
  3. Backend objects become BPMN nodes. typeName selects the card mapping; bpmnType wins over name-based start/end/gateway inference.
  4. Backend links 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.

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 a legacy declared shape. The current existing-edge renderer ignores it and derives connectors from backend links.
  • 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.

Minimal configuration

json
{
  "id": "workflow",
  "type": "bpmn",
  "request": {
    "parent": "WFEntityInstance",
    "method": "getWorkFlowGraphState",
    "objects": [],
    "params": {}
  },
  "graph": {
    "readOnly": true,
    "toolbar": { "items": [] },
    "nodes": [],
    "edges": []
  }
}

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": []
      }
    ],
    "edges": []
  }
}

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 configurator 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 links. 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.