fix: prevent workflow canvas clearing due to race condition and viewport errors (#25003)

This commit is contained in:
lyzno1 2025-09-02 20:53:44 +08:00 committed by GitHub
parent 1fce1a61d4
commit 1d1bb9451e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 21 additions and 4 deletions

View File

@ -37,7 +37,15 @@ export const useNodesSyncDraft = () => {
if (appId) {
const nodes = getNodes()
// Allow empty workflows - sync restrictions removed to support empty workflow editing
// Prevent syncing empty workflow if React Flow isn't properly initialized
// Check multiple indicators of uninitialized state:
// 1. Empty nodes with default viewport (x=0, y=0, zoom=1)
// 2. Empty edges array along with empty nodes
if (nodes.length === 0 && edges.length === 0 && x === 0 && y === 0 && zoom === 1) {
// This appears to be an uninitialized React Flow state, skip sync to prevent data loss
return null
}
const features = featuresStore!.getState().features
const producedNodes = produce(nodes, (draft) => {

View File

@ -19,7 +19,13 @@ export const useWorkflowRefreshDraft = () => {
} = workflowStore.getState()
setIsSyncingWorkflowDraft(true)
fetchWorkflowDraft(`/apps/${appId}/workflows/draft`).then((response) => {
handleUpdateWorkflowCanvas(response.graph as WorkflowDataUpdater)
// Ensure we have a valid workflow structure with viewport
const workflowData: WorkflowDataUpdater = {
nodes: response.graph?.nodes || [],
edges: response.graph?.edges || [],
viewport: response.graph?.viewport || { x: 0, y: 0, zoom: 1 },
}
handleUpdateWorkflowCanvas(workflowData)
setSyncWorkflowDraftHash(response.hash)
setEnvSecrets((response.environment_variables || []).filter(env => env.value_type === 'secret').reduce((acc, env) => {
acc[env.id] = env.value

View File

@ -329,7 +329,10 @@ export const useWorkflowUpdate = () => {
edges: initialEdges(edges, nodes),
},
} as any)
setViewport(viewport)
// Only set viewport if it exists and is valid
if (viewport && typeof viewport.x === 'number' && typeof viewport.y === 'number' && typeof viewport.zoom === 'number')
setViewport(viewport)
}, [eventEmitter, reactflow])
return {

View File

@ -177,7 +177,7 @@ const GenericTable: FC<GenericTableProps> = ({
'h-6 rounded-none bg-transparent px-0 text-text-secondary',
'hover:bg-transparent focus-visible:bg-transparent group-hover/simple-select:bg-transparent',
)}
optionWrapClassName="w-26 min-w-26 z-[5] -ml-3"
optionWrapClassName="w-26 min-w-26 z-[60] -ml-3"
notClearable
/>
)