Skip to main content

Getting Started with @xond/workflow

This guide will help you set up @xond/workflow and create your first workflow.

Installation

Install @xond/workflow in your React application:

pnpm add @xond/workflow

Or if working within the Nufaza monorepo:

pnpm --filter @xond/workflow install

Peer Dependencies

@xond/workflow requires several peer dependencies:

pnpm add @headlessui/react @heroicons/react @xond/ui react react-dom react-hook-form react-router-dom

Import Styles

Import the required styles:

// src/main.tsx or src/index.tsx
import "@xond/workflow/styles.css";
import "reactflow/dist/style.css"; // ReactFlow styles

Basic Setup

1. Form Registry Context

Wrap your application with FormRegistryContext to register custom forms:

import { FormRegistryContext } from "@xond/workflow";
import { PersonalDataForm } from "./components/forms/PersonalDataForm";

function App() {
const customForms = {
PersonalDataForm: PersonalDataForm,
// Add more custom forms here
};

return (
<FormRegistryContext customForms={customForms}>
{/* Your app content */}
</FormRegistryContext>
);
}

2. Workflow Editor

Create a page for editing workflows:

import { WorkflowEditor } from "@xond/workflow";

function WorkflowEditPage({ workflowId }: { workflowId: string }) {
return (
<div className="h-screen w-screen">
<WorkflowEditor id={workflowId} />
</div>
);
}

3. Workflow Execution

Create a page for executing workflows:

import { WorkflowUI, WorkflowActions, useWorkflows } from "@xond/workflow";
import { useState } from "react";

function WorkflowExecutionPage({ instanceId }: { instanceId: string }) {
const { instance, node, values, uiStatus, setUIStatus } = useWorkflows({
entity: "workflowInstance",
id: instanceId,
actionEndpoint: "/api/workflow-instances/action",
walkEndpoint: "/api/workflow-instances/walk",
});

const [updatedData, setUpdatedData] = useState<any>(null);

const handleReturnValue = (value: { ready: boolean; data: any }) => {
setUpdatedData(value);
setUIStatus(value);
};

const handleAction = async ({ value, handle }: { value: any; handle: string }) => {
// Call API to proceed to next node
await fetch("/api/workflow-instances/action", {
method: "POST",
body: JSON.stringify({
instanceId,
handle,
value,
}),
});
// Reload instance
window.location.reload();
};

if (!node || !instance) {
return <div>Loading...</div>;
}

return (
<div className="container mx-auto p-4">
<WorkflowUI
currentNode={node}
workflowInstance={instance}
returnValue={handleReturnValue}
/>
<WorkflowActions
currentNode={node}
workflowInstance={instance}
oldValue={values}
updatedDataFromUI={updatedData}
callBack={handleAction}
/>
</div>
);
}

Creating Your First Workflow

Step 1: Open Workflow Editor

Navigate to your workflow editor page with a workflow ID (or create a new one):

// If creating new workflow
const newWorkflowId = "new";

// If editing existing workflow
const existingWorkflowId = "00000000-0000-0000-0000-000000000001";

Step 2: Add Nodes

  1. Drag Start Node from toolbar onto canvas
  2. Drag State Node for your first step
  3. Connect Start to State by dragging from Start's output handle to State's input handle
  4. Add more nodes as needed (State nodes for steps, Decision nodes for branching)

Step 3: Configure Nodes

  1. Click on a node to select it
  2. Configure node properties:
    • Code – Unique identifier
    • Name – Display name
    • Label – Short label
    • Description – Detailed description
  3. Configure UI:
    • UI Type – Select form type (e.g., MODEL_FORM, CUSTOM_FORM)
    • Form Class – For custom forms, specify component name
    • Model – For model forms, specify model name
  4. Configure Actions:
    • Add Action – Click "Add Action"
    • Action Type – Select NEXT, SUBMIT, SKIP, etc.
    • Handle – Output handle to follow (for NEXT actions)

Step 4: Save Workflow

Click "Save" button in the workflow editor. The workflow will be validated and saved to the database.

Example: Simple Registration Workflow

Here's a simple 3-step registration workflow:

  1. Start NodeState Node (Personal Data)

    • UI Type: MODEL_FORM
    • Model: Person
    • Action: NEXT → handle "0"
  2. State Node (Personal Data)State Node (Verification)

    • UI Type: OTP_FORM
    • Action: VERIFY → handle "0" (on success)
    • Action: SKIP → handle "1" (on failure)
  3. State Node (Verification)End Node

    • UI Type: END_PAGE
    • Message: "Registration Complete"

Next Steps