dify/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts
Kevin9703 6022939bf0
fix: prevent hidden-tab collaboration leader from saving stale drafts (#38997)
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-20 06:58:01 +00:00

84 lines
3.1 KiB
TypeScript

import { useCallback, useRef } from 'react'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useWorkflowUpdate } from '@/app/components/workflow/hooks'
import { useWorkflowStore } from '@/app/components/workflow/store'
import { fetchWorkflowDraft } from '@/service/workflow'
import { useWorkflowDraftGraphForCanvas } from './use-workflow-draft-graph-for-canvas'
type RefreshWorkflowDraftOptions = {
shouldApply?: () => boolean
}
export const useWorkflowRefreshDraft = () => {
const appDetail = useAppStore((s) => s.appDetail)
const workflowStore = useWorkflowStore()
const refreshSequenceRef = useRef(0)
const { handleUpdateWorkflowCanvas } = useWorkflowUpdate()
const { getWorkflowDraftGraphForCanvas } = useWorkflowDraftGraphForCanvas(appDetail?.mode)
const handleRefreshWorkflowDraft = useCallback(
(notUpdateCanvas?: boolean, options?: RefreshWorkflowDraftOptions) => {
if (options?.shouldApply && !options.shouldApply()) return Promise.resolve(false)
const {
appId,
setSyncWorkflowDraftHash,
setIsSyncingWorkflowDraft,
setEnvironmentVariables,
setEnvSecrets,
setConversationVariables,
setIsWorkflowDataLoaded,
isWorkflowDataLoaded,
debouncedSyncWorkflowDraft,
} = workflowStore.getState()
debouncedSyncWorkflowDraft?.cancel?.()
const wasLoaded = isWorkflowDataLoaded
if (wasLoaded && !options?.shouldApply) setIsWorkflowDataLoaded(false)
const refreshSequence = ++refreshSequenceRef.current
setIsSyncingWorkflowDraft(true)
return fetchWorkflowDraft(`/apps/${appId}/workflows/draft`)
.then((response) => {
if (options?.shouldApply && !options.shouldApply()) return false
// Ensure we have a valid workflow structure with viewport
if (!notUpdateCanvas)
handleUpdateWorkflowCanvas(getWorkflowDraftGraphForCanvas(response.graph))
setSyncWorkflowDraftHash(response.hash)
setEnvSecrets(
(response.environment_variables || [])
.filter((env) => env.value_type === 'secret')
.reduce(
(acc, env) => {
acc[env.id] = env.value
return acc
},
{} as Record<string, string>,
),
)
setEnvironmentVariables(
response.environment_variables?.map((env) =>
env.value_type === 'secret' ? { ...env, value: '[__HIDDEN__]' } : env,
) || [],
)
setConversationVariables(response.conversation_variables || [])
setIsWorkflowDataLoaded(true)
return true
})
.catch(() => {
if (wasLoaded && !options?.shouldApply) setIsWorkflowDataLoaded(true)
return false
})
.finally(() => {
if (refreshSequence === refreshSequenceRef.current) setIsSyncingWorkflowDraft(false)
})
},
[getWorkflowDraftGraphForCanvas, handleUpdateWorkflowCanvas, workflowStore],
)
return {
handleRefreshWorkflowDraft,
}
}