Flow Component Props & Events
Flow Component Props & Events
Section titled “Flow Component Props & Events”Complete reference for the <flow-component> custom element API.
Events
Section titled “Events”| Event | Payload | Description |
|---|---|---|
action | (action: Item, value: unknown, patch?: any) | Triggered when a node form action is clicked |
runNode | (nodeId: string) | Triggered when user requests node execution |
change | (change: FlowChange) | Emitted when nodes/edges are added, removed, or repositioned |
Event Details
Section titled “Event Details”action
Section titled “action”Triggered when an action button within a node’s configuration form is clicked:
<template> <flow-component @action="handleAction" /></template>
<script setup>function handleAction(action, value, patch) { // action.value: Action identifier (e.g., "add.connection") // action.label: Display label // value: Current field value // patch: Optional patch data
if (action.value === 'add.connection') { const newConnection = await openConnectionDialog(); // Update node with new connection options }}</script>runNode
Section titled “runNode”Triggered when the user clicks the “Run” button on a node. Use this to execute the node on your backend:
<template> <flow-component @run-node="handleRunNode" /></template>
<script setup>async function handleRunNode(nodeId) { const { getFlow, pushingNode, pushNode } = window.$useFlowCore;
// Get current flow state const flow = getFlow(); const node = flow.nodes.find(n => n.id === nodeId);
try { // Execute on backend const result = await api.executeNode(nodeId, { flow, nodeData: node.data, });
// Update flow with execution result pushNode({ node, status: 'success', outputs: [{ data: result }], edges: result.nextEdges, }); } catch (error) { pushNode({ node, status: 'error', message: error.message, }); }}</script>change
Section titled “change”Emitted whenever the flow structure is modified:
<template> <flow-component @change="handleChange" /></template>
<script setup>function handleChange(change) { // change.id: ID of the affected element // change.element: 'node' | 'edge' // change.type: 'add' | 'remove' | 'position'
console.log(`${change.element} ${change.id} was ${change.type}d`);
// Auto-save on changes if (change.type === 'add' || change.type === 'remove') { debouncedSave(); }}
const debouncedSave = useDebounceFn(() => { const { getFlow } = window.$useFlowCore; saveFlow(getFlow());}, 1000);</script>FlowChange Type
Section titled “FlowChange Type”interface FlowChange { id: string; element: 'node' | 'edge'; type: 'add' | 'remove' | 'position';}Usage Examples
Section titled “Usage Examples”Complete Flow Editor
Section titled “Complete Flow Editor”<script setup lang="ts">import { onMounted, ref } from 'vue';
const flowId = ref('workflow-1');
onMounted(async () => { const { configure, setFlow } = window.$useFlowCore;
// Load available actions from API const apps = await api.getAvailableApps(); configure('ion.action', apps);
// Load existing flow const savedFlow = await api.getFlow(flowId.value); if (savedFlow) { setFlow(savedFlow); }});
function handleAction(action: any, value: unknown, patch?: any) { switch (action.value) { case 'add.connection': openConnectionModal(); break; case 'configure.webhook': openWebhookConfig(value); break; }}
async function handleRunNode(nodeId: string) { const { getFlow, pushingNode, pushNode, reset } = window.$useFlowCore;
// Reset previous execution state reset(nodeId);
const flow = getFlow();
// Show loading state pushingNode({ node: nodeId, queue: { edge_id: null, target: nodeId }, });
try { const result = await api.post('/execute', { flowId: flowId.value, nodeId, flow, });
pushNode({ node: { id: nodeId, data: result.nodeData }, status: 'success', outputs: result.outputs, edges: result.processedEdges, }); } catch (error) { pushNode({ node: { id: nodeId }, status: 'error', message: error.message, }); }}
function handleChange(change: { id: string; element: string; type: string }) { console.log('Flow modified:', change);
// Track unsaved changes hasUnsavedChanges.value = true;}
async function saveFlow() { const { getFlow } = window.$useFlowCore; const flowData = getFlow();
await api.saveFlow(flowId.value, flowData); hasUnsavedChanges.value = false;}</script>
<template> <div class="flow-editor"> <header> <h1>Workflow Editor</h1> <button @click="saveFlow" :disabled="!hasUnsavedChanges"> Save </button> </header>
<flow-component @action="handleAction" @run-node="handleRunNode" @change="handleChange" style="height: calc(100vh - 60px);" /> </div></template>