Overview
Screen steps are user interface components that allow human interaction within a workflow. They are implemented as React components that use the useScreenFunctions
hook to interact with the workflow system.
Basic Concepts
Screen steps work by:
- Pausing the workflow when the step is reached
- Rendering a React component to collect user input
- Collecting the user’s response through the React component
- Resuming the workflow with the collected data
This allows you to create workflows that combine automation with human decision-making and data entry.
Creating Your First Screen Step
Let’s start with a simple screen that greets a user and collects their confirmation:
./src/screens/greeting-screen.tsx
import ActionBar from "@/components/ui/action-bar";
import { useScreenFunctions } from "@samplehc/ui/contexts";
const GreetingScreen = ({ name }: { name: string }) => {
const { handleComplete } = useScreenFunctions();
return (
<div>
<h2>Hello, {name}!</h2>
<p>Ready to continue with the workflow?</p>
<ActionBar onConfirm={() => handleComplete({ result: "confirmed" })} />
</div>
);
};
export default GreetingScreen;
Adding Screen Steps to Workflows
Once you’ve created a screen component, add it to your workflow definition:
from workflows_py.workflow import ScreenStep, Step, Workflow
workflow = Workflow()
workflow.then(
Step("prepare-greeting", lambda ctx: {"user_name": "John"})
).then(
ScreenStep("greeting", screen_path="./screens/greeting-screen.tsx", get_props=lambda ctx: {"name": ctx.get_step_result("prepare-greeting")["user_name"]})
)
The screen component receives props from the get_props
function. In this example, the name
prop comes from the user_name
field returned by the "prepare-greeting"
step.
The useScreenFunctions Hook
Screen components interact with the workflow system using the useScreenFunctions
hook, which provides two essential functions:
handleComplete({ result: data })
- Completes the screen step and passes data
to the workflow. The workflow continues to the next step.
handleCancel()
- Cancels the screen step and stops workflow execution.
Screen Step Data Flow
Understanding how data flows through screen steps is crucial:
- Input Data: Screen components receive props from the previous workflow step’s output
- User Interaction: Users interact with the screen interface to provide input
- Completion Data: When
handleComplete()
is called, the data passed becomes the step’s output
- Next Step Access: Subsequent steps can access this data using
ctx.get_step_result("step-id")
# Accessing screen step results in the next workflow step
workflow.then(
ScreenStep("user-input", "./screens/input-screen.tsx")
).then(
Step("process-input", lambda ctx: {
"user_data": ctx.get_step_result("user-input")
})
)
Advanced Example: Document Upload Screen
Here’s a more complex example that demonstrates form handling and file uploads:
./src/screens/document-upload-screen.tsx
import { useScreenFunctions } from "@samplehc/ui/contexts";
import { Form } from "@samplehc/ui/components";
const DocumentUploadScreen = () => {
const { handleComplete, handleCancel } = useScreenFunctions();
return (
<div>
<h2>Upload Documents</h2>
<Form
elements={[
{
key: "documents",
label: "Documents",
type: "document",
allowMultiple: true,
description: "Upload multiple PDF documents or a ZIP file",
},
{
key: "accession_id",
label: "Accession ID",
type: "text",
required: true,
},
]}
onSubmit={async (formData) => {
await handleComplete({
result: {
documents: formData.documents,
accessionId: formData.accession_id
}
});
}}
onCancel={() => handleCancel()}
/>
</div>
);
};
export default DocumentUploadScreen;
This screen:
- Renders a form with document upload and text input fields
- Validates required fields before submission
- Structures the output data for easy access by subsequent workflow steps
- Provides a cancel option for users
Best Practices
Design Clear Interfaces
- Use descriptive labels and helpful descriptions for form fields
- Provide clear instructions about what input is expected
- Include visual feedback for loading states and form validation
Handle Errors Gracefully
- Validate user input before calling
handleComplete()
- Display clear error messages for invalid inputs
- Provide users with actionable guidance to resolve issues
Structure Output Data
- Use consistent naming conventions for output data
- Group related data into objects for easier access
- Include all necessary information for downstream workflow steps
Consider User Experience
- Keep forms focused and avoid overwhelming users with too many fields
- Provide progress indicators for multi-step processes
- Allow users to save drafts or return to previous steps when appropriate
Responses are generated using AI and may contain mistakes.