Flow Studio
How the Form Renders
The rendering chain: HIL inbox task → WorkDesk task view → FormRenderer component → Atlas Forms player → user interaction.
Rendering Chain
UserFormNode suspends
│
▼
HIL Task created (executionId, nodeId, formId, initialValues)
│
▼
WorkDesk Inbox shows new task notification
│
Actor opens task
▼
HIL Inbox API: GET /api/hil-tasks/{taskId}
Returns: { formId, initialValues, executionContext, ... }
│
▼
FormRenderer component mounts
Loads Atlas Forms definition for formId
Applies initialValues as field defaults
│
User fills form fields
│
Submit button clicked
▼
FormRenderer calls:
POST /api/executions/{executionId}/resume
{ responseData: { fieldKey: value, ... } }
│
▼
Workflow resumes — UserFormNode output = responseData
FormRenderer Component
// packages/player-components-react/src/components/FormRenderer.tsx
interface FormRendererProps {
formId: string;
initialValues?: Record<string, unknown>;
executionId: string;
taskId: string;
onSubmit?: (values: Record<string, unknown>) => void;
onCancel?: () => void;
}
export function FormRenderer({
formId, initialValues, executionId, taskId, onSubmit, onCancel
}: FormRendererProps) {
const { form, loading } = useAtlasForm(formId);
const { submit } = useHILResume(executionId);
async function handleSubmit(values: Record<string, unknown>) {
await submit({ responseData: values, action: 'submit' });
onSubmit?.(values);
}
if (loading) return <FormSkeleton />;
return <AtlasFormPlayer form={form} initialValues={initialValues} onSubmit={handleSubmit} onCancel={onCancel} />;
}
Task Payload Structure
{
"taskId": "task-abc123",
"taskType": "UserForm",
"formId": "form-employee-expense-request",
"title": "Expense Approval Request",
"description": "Please review and submit the expense claim",
"initialValues": {
"employeeId": "emp-001",
"claimAmount": 450.00,
"currency": "USD",
"category": "travel"
},
"executionId": "exec-100",
"assignedTo": "user-manager-bob",
"createdAt": "2026-05-25T10:00:00Z",
"dueAt": "2026-05-26T10:00:00Z"
}