StepDefinition
StepDefinition defines a single step in a flow. Each step can be an action, event handling, or other operation. A step is the basic execution unit of a flow.
Type Definition
interface StepDefinition<TModel extends FlowModel = FlowModel>
extends Partial<Omit<ActionDefinition<TModel, FlowRuntimeContext<TModel>>, 'name'>> {
key?: string;
isAwait?: boolean;
use?: string;
sort?: number;
preset?: boolean;
paramsRequired?: boolean;
hideInSettings?: boolean;
uiMode?: StepUIMode | ((ctx: FlowRuntimeContext<TModel>) => StepUIMode | Promise<StepUIMode>);
}
Usage
class MyModel extends FlowModel {}
MyModel.registerFlow({
key: 'pageSettings',
steps: {
step1: {
use: 'actionName',
title: 'First Step',
sort: 0,
preset: true
},
step2: {
handler: async (ctx, params) => {
// Custom processing logic
return { result: 'success' };
},
title: 'Second Step',
sort: 1
}
}
});
Property Descriptions
key
Type: string
Required: No
Description: The unique identifier for the step within the flow.
If not provided, the key name of the step in the steps object will be used.
Example:
steps: {
loadData: { // key is 'loadData'
use: 'loadDataAction'
}
}
use
Type: string
Required: No
Description: The name of a registered ActionDefinition to use.
The use property allows you to reference a registered action, avoiding duplicate definitions.
Example:
// Register the action first
MyModel.registerAction({
name: 'loadDataAction',
handler: async (ctx, params) => {
// Data loading logic
}
});
// Use it in a step
steps: {
step1: {
use: 'loadDataAction', // Reference the registered action
title: 'Load Data'
}
}
title
Type: string
Required: No
Description: The display title of the step.
Used for UI display and debugging.
Example:
title: 'Load Data'
title: 'Process Information'
title: 'Save Results'
sort
Type: number
Required: No
Description: The execution order of the step. The smaller the value, the earlier it executes.
Used to control the execution order of multiple steps in the same flow.
Example:
steps: {
step1: { sort: 0 }, // Executes first
step2: { sort: 1 }, // Executes next
step3: { sort: 2 } // Executes last
}
handler
Type: (ctx: FlowRuntimeContext<TModel>, params: any) => Promise<any> | any
Required: No
Description: The handler function for the step.
When the use property is not used, you can define the handler function directly.
Example:
handler: async (ctx, params) => {
// Get context information
const { model, flowEngine } = ctx;
// Processing logic
const result = await processData(params);
// Return result
return { success: true, data: result };
}
defaultParams
Type: Record<string, any> | ((ctx: FlowRuntimeContext<TModel>) => Record<string, any> | Promise<Record<string, any>>)
Required: No
Description: The default parameters for the step.
Fills parameters with default values before the step is executed.
Example:
// Static default parameters
defaultParams: {
timeout: 5000,
retries: 3,
format: 'json'
}
// Dynamic default parameters
defaultParams: (ctx) => {
return {
userId: ctx.model.uid,
timestamp: Date.now()
}
}
// Asynchronous default parameters
defaultParams: async (ctx) => {
const config = await loadConfig();
return {
apiUrl: config.apiUrl,
apiKey: config.apiKey
}
}
uiSchema
Type: Record<string, ISchema> | ((ctx: FlowRuntimeContext<TModel>) => Record<string, ISchema> | Promise<Record<string, ISchema>>)
Required: No
Description: The UI configuration schema for the step.
Defines how the step is displayed in the interface and its form configuration.
Example:
uiSchema: {
'x-component': 'Form',
'x-component-props': {
layout: 'vertical'
},
properties: {
name: {
type: 'string',
title: 'Name',
'x-component': 'Input'
},
age: {
type: 'number',
title: 'Age',
'x-component': 'InputNumber'
}
}
}
beforeParamsSave
Type: (ctx: FlowSettingsContext<TModel>, params: any, previousParams: any) => void | Promise<void>
Required: No
Description: A hook function that runs before the parameters are saved.
Executes before the step parameters are saved, and can be used for parameter validation or transformation.
Example:
beforeParamsSave: (ctx, params, previousParams) => {
// Parameter validation
if (!params.name) {
throw new Error('Name is required');
}
// Parameter transformation
params.name = params.name.trim().toLowerCase();
}
afterParamsSave
Type: (ctx: FlowSettingsContext<TModel>, params: any, previousParams: any) => void | Promise<void>
Required: No
Description: A hook function that runs after the parameters are saved.
Executes after the step parameters are saved, and can be used to trigger other operations.
Example:
afterParamsSave: (ctx, params, previousParams) => {
// Record logs
console.log('Step params saved:', params);
// Trigger other operations
ctx.model.emitter.emit('paramsChanged', params);
}
uiMode
Type: StepUIMode | ((ctx: FlowRuntimeContext<TModel>) => StepUIMode | Promise<StepUIMode>)
Required: No
Description: The UI display mode for the step.
Controls how the step is displayed in the interface.
Supported modes:
'dialog' - Dialog mode
'drawer' - Drawer mode
'embed' - Embed mode
- Or a custom configuration object
Example:
// Simple mode
uiMode: 'dialog'
// Custom configuration
uiMode: {
type: 'dialog',
props: {
width: 800,
title: 'Step Configuration'
}
}
// Dynamic mode
uiMode: (ctx) => {
return ctx.model.isMobile ? 'drawer' : 'dialog';
}
preset
Type: boolean
Required: No
Description: Whether it is a preset step.
Parameters for steps with preset: true need to be filled in at creation time. Those without this flag can be filled in after the model is created.
Example:
steps: {
step1: {
preset: true, // Parameters must be filled in at creation time
use: 'requiredAction'
},
step2: {
preset: false, // Parameters can be filled in later
use: 'optionalAction'
}
}
paramsRequired
Type: boolean
Required: No
Description: Whether the step parameters are required.
If true, a configuration dialog will open before adding the model.
Example:
paramsRequired: true // Parameters must be configured before adding the model
paramsRequired: false // Parameters can be configured later
hideInSettings
Type: boolean
Required: No
Description: Whether to hide the step in the settings menu.
Example:
hideInSettings: true // Hide in settings
hideInSettings: false // Show in settings (default)
isAwait
Type: boolean
Required: No
Default: true
Description: Whether to wait for the handler function to complete.
Example:
isAwait: true // Wait for the handler function to complete (default)
isAwait: false // Do not wait, execute asynchronously
Complete Example
class DataProcessingModel extends FlowModel {}
DataProcessingModel.registerFlow({
key: 'dataProcessing',
title: 'Data Processing',
steps: {
loadData: {
use: 'loadDataAction',
title: 'Load Data',
sort: 0,
preset: true,
paramsRequired: true,
defaultParams: {
source: 'api',
timeout: 5000
},
uiMode: 'dialog'
},
processData: {
handler: async (ctx, params) => {
const data = await ctx.model.getData();
return processData(data, params);
},
title: 'Process Data',
sort: 1,
defaultParams: (ctx) => ({
userId: ctx.model.uid,
timestamp: Date.now()
}),
beforeParamsSave: (ctx, params) => {
if (!params.processor) {
throw new Error('Processor is required');
}
},
afterParamsSave: (ctx, params) => {
ctx.model.emitter.emit('dataProcessed', params);
}
},
saveData: {
use: 'saveDataAction',
title: 'Save Data',
sort: 2,
hideInSettings: false,
uiMode: {
type: 'drawer',
props: {
width: 600,
title: 'Save Configuration'
}
}
}
}
});