mirror of
https://github.com/langgenius/dify.git
synced 2026-01-05 22:15:52 +00:00
fix: prevent empty workflow draft sync during page navigation (#25140)
This commit is contained in:
@@ -33,19 +33,15 @@ export const useNodesSyncDraft = () => {
|
||||
conversationVariables,
|
||||
environmentVariables,
|
||||
syncWorkflowDraftHash,
|
||||
isWorkflowDataLoaded,
|
||||
} = workflowStore.getState()
|
||||
|
||||
if (appId) {
|
||||
const nodes = getNodes()
|
||||
|
||||
// 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
|
||||
// Prevent sync if workflow data hasn't been loaded yet
|
||||
if (!isWorkflowDataLoaded)
|
||||
return null
|
||||
}
|
||||
|
||||
const features = featuresStore!.getState().features
|
||||
const producedNodes = produce(nodes, (draft) => {
|
||||
|
||||
@@ -49,6 +49,7 @@ export const useWorkflowInit = () => {
|
||||
}, {} as Record<string, string>),
|
||||
environmentVariables: res.environment_variables?.map(env => env.value_type === 'secret' ? { ...env, value: '[__HIDDEN__]' } : env) || [],
|
||||
conversationVariables: res.conversation_variables || [],
|
||||
isWorkflowDataLoaded: true,
|
||||
})
|
||||
setSyncWorkflowDraftHash(res.hash)
|
||||
setIsLoading(false)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
useEffect,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
import useSWR from 'swr'
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
import {
|
||||
useWorkflowInit,
|
||||
} from './hooks'
|
||||
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||
import {
|
||||
initialEdges,
|
||||
initialNodes,
|
||||
@@ -32,9 +34,24 @@ const WorkflowAppWithAdditionalContext = () => {
|
||||
data,
|
||||
isLoading,
|
||||
} = useWorkflowInit()
|
||||
const workflowStore = useWorkflowStore()
|
||||
const { isLoadingCurrentWorkspace, currentWorkspace } = useAppContext()
|
||||
const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig)
|
||||
|
||||
// Cleanup on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
// Reset the loaded flag when component unmounts
|
||||
workflowStore.setState({ isWorkflowDataLoaded: false })
|
||||
|
||||
// Cancel any pending debounced sync operations
|
||||
const { debouncedSyncWorkflowDraft } = workflowStore.getState()
|
||||
// The debounced function from lodash has a cancel method
|
||||
if (debouncedSyncWorkflowDraft && 'cancel' in debouncedSyncWorkflowDraft)
|
||||
(debouncedSyncWorkflowDraft as any).cancel()
|
||||
}
|
||||
}, [workflowStore])
|
||||
|
||||
const nodesData = useMemo(() => {
|
||||
if (data)
|
||||
return initialNodes(data.graph.nodes, data.graph.edges)
|
||||
|
||||
@@ -21,6 +21,8 @@ export type WorkflowDraftSliceShape = {
|
||||
setSyncWorkflowDraftHash: (hash: string) => void
|
||||
isSyncingWorkflowDraft: boolean
|
||||
setIsSyncingWorkflowDraft: (isSyncingWorkflowDraft: boolean) => void
|
||||
isWorkflowDataLoaded: boolean
|
||||
setIsWorkflowDataLoaded: (loaded: boolean) => void
|
||||
}
|
||||
|
||||
export const createWorkflowDraftSlice: StateCreator<WorkflowDraftSliceShape> = set => ({
|
||||
@@ -33,4 +35,6 @@ export const createWorkflowDraftSlice: StateCreator<WorkflowDraftSliceShape> = s
|
||||
setSyncWorkflowDraftHash: syncWorkflowDraftHash => set(() => ({ syncWorkflowDraftHash })),
|
||||
isSyncingWorkflowDraft: false,
|
||||
setIsSyncingWorkflowDraft: isSyncingWorkflowDraft => set(() => ({ isSyncingWorkflowDraft })),
|
||||
isWorkflowDataLoaded: false,
|
||||
setIsWorkflowDataLoaded: loaded => set(() => ({ isWorkflowDataLoaded: loaded })),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user