Skip to content

Visual Workflow Editor

The visual workflow editor lets administrators design event-driven automation workflows through a node-based canvas powered by Rete.js v2 with an Unreal Engine 4 Blueprint aesthetic.


Overview

PropertyValue
Route/admin-panel/workflows
Feature flagFEATURE_WORKFLOWS=true
Main pageapp/pages/admin-panel/workflows.vue
Storeapp/stores/workflowEditor.ts
Node typesACTION, COMPUTE, SWITCH, JOIN, DELAY, END

Architecture

useWorkflowEditorStore Pinia store

Manages the full Rete.js lifecycle inside a Nuxt context, with integrated undo/redo history:

Method / StateDescription
init(el)Creates editor, area, and all extensions
loadGraph(g)Converts backend graph → Rete nodes via backendToRete()
exportGraph()Converts Rete state → backend format via reteToBackend()
addNode(type)Adds a new node of the given type at center
removeNode(id)Removes the selected node (with snapshot for undo)
destroy()Tears down Rete editor and removes DOM listeners
undo() / redo()Snapshot-based undo/redo (max 30 entries)
canUndo / canRedoComputed booleans for UI button state

VuePlugin context sharingVuePlugin.setup() copies Nuxt provides, globalProperties, components, and directives into the Rete Vue root so that useColorMode(), sockets, and other Nuxt composables work inside node components.

History — implemented in stores/workflowEditor/history.ts using snapshot-based stacks (same pattern as stores/designer/history.ts). Snapshots capture node positions, config, and connections. Each mutation (add/remove/move/edit) saves a snapshot before applying changes.

Key files

FileRole
app/types/workflow.tsEventSubscription, WorkflowNode/Edge, WorkflowGraph, Run, RunNode
app/types/plugin.tsPluginDefinition, PluginInstance, PluginAction
app/stores/workflow.tsCRUD for subscriptions, graph, runs, test execution
app/stores/workflowEditor.tsPinia store — Rete lifecycle + undo/redo
app/stores/workflowEditor/history.tsSnapshot-based undo/redo composable
app/stores/workflowEditor/types.tsWorkflowSnapshot, WorkflowSnapshotNode, WorkflowSnapshotConnection
app/stores/plugin.tsPinia store — fetch(), getActionsForInstance(), getDefinitionForInstance()
app/utils/workflow/reteTypes.tsWorkflowNode, WorkflowConnection, FlowSocket, DataSocket, Schemes
app/utils/workflow/nodeDefinitions.tsNODE_DEFINITIONS — 6 types with label, icon, glowColor, inputs, outputs, defaultConfig
app/utils/workflow/graphConverter.tsbackendToRete() / reteToBackend(), positions in config._position
app/utils/workflow/keyPropagation.tsreplaceNodeKeyInGraph(), validateNodeKey() — updates references when node key changes
app/utils/workflow/schemaFields.tsextractSchemaFieldPaths() — extracts field paths from JSON schemas for autocomplete

Node Types

TypeConfig fieldsDescription
ACTIONplugin_instance_id, plugin_action, input_mappingCalls a plugin action
COMPUTElogic (JSON Logic object)Evaluates a JSON Logic expression
SWITCH(conditions defined on outgoing edges)Branches flow based on edge conditions
JOINmode, n_requiredWaits for predecessor nodes
DELAYdelay_ms, until_templatePauses execution
END(no config)Terminal node

JOIN modes:

  • ALL — waits for all predecessor nodes to complete (default)
  • ANY — proceeds as soon as any single predecessor completes
  • N_OF_M — proceeds when n_required predecessors have completed

DELAY config:

  • delay_ms (integer) — fixed delay in milliseconds
  • until_template (string | null) — template string for scheduled delays (e.g. a date/time expression); when set, the delay waits until the evaluated time instead of a fixed duration

UI Components

ComponentRole
Workflow/Rete/WorkflowNodeComponent.vueUE4-styled node card with ReteRef sockets and gradient glow
Workflow/Rete/WorkflowSocketComponent.vue16 px circle socket
Workflow/Rete/WorkflowConnectionComponent.vueBézier curve connection with CSS stroke
Workflow/Editor/WorkflowEditorToolbar.vueGlassmorphism toolbar — Undo/Redo, Arrange, Zoom, Test
Workflow/Editor/WorkflowNodePalette.vueSidebar palette — click a type to add it to the canvas
Workflow/Editor/WorkflowNodeConfigSidebar.vueShell: header + dynamic config component + delete button
Workflow/Editor/WorkflowNodeConfigAction.vuePlugin instance + action dropdowns; JsonForms or JSON textarea for input_mapping
Workflow/Editor/WorkflowNodeConfigCompute.vueJSON Logic textarea
Workflow/Editor/WorkflowNodeConfigSwitch.vueInfo panel — conditions live on edges
Workflow/Editor/WorkflowNodeConfigJoin.vuen_required integer input
Workflow/Editor/WorkflowNodeConfigDelay.vuedelay_ms integer input
Workflow/Editor/WorkflowNodeConfigEnd.vueInfo panel — terminal node
Workflow/Editor/WorkflowNodeConfigAdvanced.vueTimeout, continue-on-error, retry policy (collapsible)
Workflow/Editor/WorkflowEdgeConfigSidebar.vueEdge/connection config sidebar — label editing and JSON Logic condition builder
Workflow/Editor/JsonLogicBuilder.vueVisual JSON Logic condition builder with rule groups (AND/OR) and raw JSON mode
Workflow/Editor/JsonLogicRule.vueField / operator / value inputs with dropdown prefix selector

API Mappings

Defined in app/api.config.ts:

MethodEndpoint
eventSubscriptionList/Create/Detail/Update/DeleteCRUD for workflow subscriptions
eventSubscriptionGraphList/UpdateRead and save the workflow graph
eventSubscriptionTestTrigger a test run simulation
workflowRunList/DetailWorkflow run history and detail
workflowRunNodeListNode-level run status within a run
pluginListv1PluginDefinitionList
pluginInstanceListv1PluginInstanceList
pluginInstanceDetailv1PluginInstanceDetail

i18n Keys

  • @pages.adminPanel.tabs.workflows.* — tabs, table, actions, editor, sidebar strings
  • @modals.workflow.* — create / edit / deleteConfirm modals
  • @toasts.workflow.* — CRUD success/error toasts

Notes

  • Rete's Ref is imported as ReteRef to avoid collision with Vue's ref.
  • Node selection uses AreaExtensions.selectableNodes(); the selected node ID is tracked in a selectedNodeId ref.
  • Changing a plugin instance in the ACTION config resets both the plugin_action and input_mapping fields.
  • If a plugin action has an input_schema, the ACTION config renders a dynamic JsonForms form; otherwise a raw JSON textarea is shown.
  • Connections (edges) are selectable — clicking a connection opens WorkflowEdgeConfigSidebar where users can set a label and configure a JSON Logic condition (conditionJsonlogic). This is how SWITCH node branching conditions are defined.
  • JsonLogicBuilder provides two editing modes: a visual builder with AND/OR rule groups and a raw JSON editor for advanced conditions. Context fields (from upstream node output schemas) are available for autocomplete via extractSchemaFieldPaths().
  • Keyboard shortcutsBackspace/Delete deletes the selected node or connection; Cmd+Z/Ctrl+Z undoes; Cmd+Shift+Z/Ctrl+Shift+Z redoes. Shortcuts are ignored when typing in sidebar input fields (handled by defineShortcuts).