Skip to main content
Version: 1.6.x

Regular Approval

Regular Approval is the core element of enterprise workflow management, implementing complete approval process handling capabilities based on the JitWorkflow approval engine. It is responsible for approval node configuration, approver assignment, conditional branching, and parallel processing, supporting various approval modes and complex approval strategies to meet approval requirements in different business scenarios.

The Regular Approval element hierarchy is Meta (workflows.Meta) → Type (workflows.NormalType) → Instance. Developers can quickly create Regular Approval instance elements through JitAI's visual development tools.

Of course, developers can also create their own Type elements or modify the official workflows.NormalType element provided by JitAI in their own App to implement their own encapsulation.

Quick Start​

Create Instance Element​

Directory Structure​

Recommended Directory Structure
MyApproval/ # Approval instance name
├── e.json # Element definition file
├── config.json # Approval process configuration file
├── __init__.py # Package initialization file
└── pages/ # Optional: Custom approval pages
└── NodePage/
├── e.json
├── index.ts
├── page.style.ts
├── page.ts
├── PageRender.tsx
└── scheme.json

e.json File​

e.json Configuration Example
{
"type": "workflows.NormalType",
"icon": "IDEshenpi",
"path": "workflows",
"title": "Leave Approval",
"dataModel": "models.LeaveModel",
"frontBundleEntry": "./config.json",
"outputName": "index",
"backendBundleEntry": ".",
"platformSwitch": 0,
"syncStatus": false,
"commentSwitch": 1,
"allowPrint": 0
}

Business Configuration File​

config.json Approval Process Configuration
{
"nodeList": [
{
"name": "StartNode",
"title": "Start Node",
"type": 0,
"zIndex": 1,
"position": {"x": 0, "y": 0}
},
{
"name": "ApproveNode1",
"title": "Department Manager Approval",
"type": 1,
"zIndex": 1,
"position": {"x": 0, "y": 200}
},
{
"name": "EndNode",
"title": "End Node",
"type": 7,
"zIndex": 1,
"position": {"x": 0, "y": 400}
}
],
"linkList": [
{
"linkId": "1001",
"from": "StartNode",
"fromPort": "bottom-StartNode",
"to": "ApproveNode1",
"toPort": "top-ApproveNode1"
},
{
"linkId": "1002",
"from": "ApproveNode1",
"fromPort": "bottom-ApproveNode1",
"to": "EndNode",
"toPort": "top-EndNode"
}
],
"nodeConfig": {
"StartNode": {
"nodeName": "Start Node",
"nodeType": 0,
"digest": ["applicant", "leaveType", "startDate", "endDate"],
"handleList": [
{"buttonName": "Submit", "checked": 1, "handleType": 0},
{"buttonName": "Cancel Process", "checked": 0, "handleType": 16}
],
"fieldAccessControl": {
"read": ["applicant", "leaveType", "startDate", "endDate", "reason"],
"edit": ["applicant", "leaveType", "startDate", "endDate", "reason"]
}
},
"ApproveNode1": {
"nodeName": "Department Manager Approval",
"nodeType": 1,
"approver": {
"approveType": 1,
"userIdList": ["${directLeader}"]
},
"handleList": [
{"buttonName": "Approve", "checked": 1, "handleType": 2},
{"buttonName": "Reject", "checked": 1, "handleType": 3}
]
},
"EndNode": {
"nodeName": "End Node",
"nodeType": 7
}
},
"modelName": "models.LeaveModel",
"statusMaps": {}
}

Usage Example​

Get and Operate Approval Instance
# Get approval instance
approval = app.getElement("workflows.MyApproval")

# Initiate approval
result = approval.doHandle(
handleType=0, # Submit operation
nodeId="StartNode", # Start node
row=leave_data, # Approval data
valueDict={"comment": "Emergency leave"} # Approval comment
)

# Get next approval node
next_nodes = approval.getNextNodes("StartNode")

# Get approval node configuration
node_config = approval.getNode("ApproveNode1")

Element Configuration​

e.json Configuration​

ParameterTypeNative TypeRequiredDescription
typeStextstrYesFixed value: workflows.NormalType
titleStextstrYesApproval process title
dataModelStextstrYesAssociated data model fullName
iconStextstrNoApproval icon identifier
platformSwitchNumericintNoPlatform switch, 0 off 1 on
commentSwitchNumericintNoComment switch, 0 off 1 on
allowPrintNumericintNoPrint permission, 0 not allowed 1 allowed
syncStatusJitDictboolNoSync status setting
allowShareNumericintNoShare permission, 0 not allowed 1 allowed
showPredictNumericintNoPrediction permission, 0 not shown 1 shown

Business Configuration File Configuration​

ParameterTypeNative TypeRequiredDescription
nodeListJitListlistYesApproval node list configuration
linkListJitListlistYesNode connection relationship configuration
nodeConfigJitDictdictYesDetailed configuration for each node
modelNameStextstrYesData model name
statusMapsJitDictdictNoStatus mapping configuration

Methods​

doHandle​

Execute approval operations, handling various approval actions.

Parameters​

ParameterTypeNative TypeRequiredDescription
handleTypeNumericintYesOperation type: 0 submit, 2 approve, 3 reject, etc.
nodeIdStextstrYesTarget node ID
rowRowDataobjectYesApproval data row object
valueDictJitDictdictNoAdditional parameters for approval operation

Return Value​

No return value, directly executes approval operation.

Usage Example​

Execute Approval Operations
# Initiate approval
approval.doHandle(
handleType=0,
nodeId="StartNode",
row=data_row,
valueDict={"comment": "Application reason"}
)

# Approve
approval.doHandle(
handleType=2,
nodeId="ApproveNode1",
row=data_row,
valueDict={"approveComment": "Approve application"}
)

# Reject
approval.doHandle(
handleType=3,
nodeId="ApproveNode1",
row=data_row,
valueDict={"rejectReason": "Incomplete materials"}
)

getNode​

Get the configuration object of the specified approval node.

Parameters​

ParameterTypeNative TypeRequiredDescription
nodeIdStextstrYesNode ID identifier

Return Value​

Returns node configuration object containing complete node configuration information.

Usage Example​

Get Node Configuration
# Get approval node
node = approval.getNode("ApproveNode1")

# Check node type
node_type = node.nodeType

# Get approver configuration
approver_config = node.approver if hasattr(node, 'approver') else None

getNextNodes​

Get the list of downstream flow nodes for the specified node.

Parameters​

ParameterTypeNative TypeRequiredDescription
nodeIdStextstrYesCurrent node ID

Return Value​

Returns list of downstream node objects, arranged in flow order.

Usage Example​

Get Downstream Nodes
# Get downstream nodes of start node
next_nodes = approval.getNextNodes("StartNode")

# Iterate through downstream nodes
for node in next_nodes:
print(f"Downstream node: {node.name} - {node.nodeType}")

# Check if there are downstream nodes
if next_nodes:
first_next = next_nodes[0]

getStartNode​

Get the start node of the approval process.

Return Value​

Returns start node object.

Usage Example​

Get Start Node
# Get process start node
start_node = approval.getStartNode()

# View start node configuration
start_config = start_node.nodeConfigDict

getStartNodeId​

Get the start node ID of the approval process.

Return Value​

Returns start node ID string.

Usage Example​

Get Start Node ID
# Get start node ID
start_id = approval.getStartNodeId()

# Get node object based on start node ID
start_node = approval.getNode(start_id)

getApproveNodeIdList​

Get the ID list of all approval nodes.

Return Value​

Returns list of approval node IDs.

Usage Example​

Get Approval Node List
# Get all approval node IDs
approve_ids = approval.getApproveNodeIdList()

# Iterate through approval nodes
for node_id in approve_ids:
node = approval.getNode(node_id)
print(f"Approval node: {node_id} - {node.name}")

getPrevNodes​

Get the list of predecessor nodes for the specified node.

Parameters​

ParameterTypeNative TypeRequiredDescription
nodeIdStextstrYesTarget node ID

Return Value​

Returns list of predecessor node objects.

Usage Example​

Get Predecessor Nodes
# Get predecessor nodes of specified node
prev_nodes = approval.getPrevNodes("EndNode")

# Check predecessor nodes
for node in prev_nodes:
print(f"Predecessor node: {node.name}")

clear​

Reset approval instance state for multiple approval initiations within the same request.

Usage Example​

Reset Approval State
# Reset state between multiple operations
approval.clear()

# Can perform new approval operations after reset
approval.doHandle(handleType=0, nodeId="StartNode", row=new_data)

Properties​

workflowName​

Name of the current approval process, read-only property.

workflowTitle​

Display title of the current approval process, read-only property.

platformSwitch​

Platform switch state, read-only property.

Connection relationship configuration of the approval process, read-only property.

tableId​

Associated data model identifier, read-only property.

Advanced Features​

Complex Approval Process Configuration​

For complex scenarios including conditional branching, parallel approval, and sub-processes, more complex node types and connection relationships can be configured in config.json:

Complex Process Configuration Example
{
"nodeList": [
{"name": "StartNode", "title": "Start", "type": 0},
{"name": "BranchNode", "title": "Conditional Branch", "type": 4},
{"name": "ParallelStart", "title": "Parallel Start", "type": 5},
{"name": "Approve1", "title": "Approval 1", "type": 1},
{"name": "Approve2", "title": "Approval 2", "type": 1},
{"name": "ParallelEnd", "title": "Parallel End", "type": 6},
{"name": "EndNode", "title": "End", "type": 7}
],
"nodeConfig": {
"BranchNode": {
"nodeType": 4,
"branchRule": {
"conditions": [
{"field": "amount", "operator": ">", "value": 10000, "target": "ParallelStart"},
{"field": "amount", "operator": "<=", "value": 10000, "target": "EndNode"}
]
}
},
"ParallelStart": {
"nodeType": 5,
"parallelConfig": {
"targetNodes": ["Approve1", "Approve2"],
"mergeRule": "all"
}
}
}
}

Custom Approval Pages​

By creating custom page components in the pages directory, personalized approval interfaces can be implemented:

Custom Approval Page Example
// pages/NodePage/PageRender.tsx
import React from 'react';

export const ApprovalPageRender = (props) => {
const { nodeConfig, formData, onSubmit } = props;

return (
<div className="custom-approval-page">
<h2>{nodeConfig.title}</h2>
{/* Custom form component */}
<CustomForm data={formData} onSubmit={onSubmit} />
</div>
);
};