mirror of
https://github.com/langgenius/dify.git
synced 2026-02-09 15:10:13 -05:00
fix: Fix race condition in prompt editor reference sync
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -222,6 +222,7 @@ mise.toml
|
||||
|
||||
|
||||
# AI Assistant
|
||||
.sisyphus/
|
||||
.roo/
|
||||
api/.env.backup
|
||||
/clickzetta
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
Fragment,
|
||||
memo,
|
||||
useCallback,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react'
|
||||
@@ -71,6 +72,19 @@ type ComponentPickerProps = {
|
||||
isSupportFileVar?: boolean
|
||||
isSupportSandbox?: boolean
|
||||
}
|
||||
|
||||
type ReferenceSyncProps = {
|
||||
anchor: HTMLElement | null
|
||||
setReference: (node: HTMLElement | null) => void
|
||||
}
|
||||
|
||||
const ReferenceSync = ({ anchor, setReference }: ReferenceSyncProps) => {
|
||||
useLayoutEffect(() => {
|
||||
setReference(anchor)
|
||||
}, [anchor, setReference])
|
||||
return null
|
||||
}
|
||||
|
||||
const ComponentPicker = ({
|
||||
triggerString,
|
||||
contextBlock,
|
||||
@@ -265,14 +279,12 @@ const ComponentPicker = ({
|
||||
if (!(anchorElementRef.current && (isSandboxMenu || allFlattenOptions.length || workflowVariableBlock?.show)))
|
||||
return null
|
||||
|
||||
setTimeout(() => {
|
||||
if (anchorElementRef.current)
|
||||
refs.setReference(anchorElementRef.current)
|
||||
}, 0)
|
||||
const anchorElement = anchorElementRef.current
|
||||
|
||||
if (isSandboxMenu) {
|
||||
return (
|
||||
<>
|
||||
<ReferenceSync anchor={anchorElement} setReference={refs.setReference} />
|
||||
{ReactDOM.createPortal(
|
||||
<div className="h-0 w-0">
|
||||
<div
|
||||
@@ -347,7 +359,7 @@ const ComponentPicker = ({
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
anchorElementRef.current,
|
||||
anchorElement,
|
||||
)}
|
||||
</>
|
||||
)
|
||||
@@ -355,6 +367,7 @@ const ComponentPicker = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<ReferenceSync anchor={anchorElement} setReference={refs.setReference} />
|
||||
{
|
||||
ReactDOM.createPortal(
|
||||
<div className="h-0 w-0">
|
||||
@@ -443,7 +456,7 @@ const ComponentPicker = ({
|
||||
)}
|
||||
</div>
|
||||
</div>,
|
||||
anchorElementRef.current,
|
||||
anchorElement,
|
||||
)
|
||||
}
|
||||
</>
|
||||
|
||||
@@ -647,7 +647,7 @@ const useOneStepRun = <T>({
|
||||
return null
|
||||
}, [flowId, id, data, handleNodeDataUpdate, cancelPluginSingleRun])
|
||||
|
||||
const checkValidWrap = () => {
|
||||
const checkValidWrap = useCallback(() => {
|
||||
if (!checkValid)
|
||||
return { isValid: true, errorMessage: '' }
|
||||
const res = checkValid(data, t, moreDataForCheckValid)
|
||||
@@ -665,7 +665,8 @@ const useOneStepRun = <T>({
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
}, [checkValid, data, handleNodeDataUpdate, id, t, moreDataForCheckValid])
|
||||
|
||||
const [canShowSingleRun, setCanShowSingleRun] = useState(false)
|
||||
const isShowSingleRun = data._isSingleRun && canShowSingleRun
|
||||
const [iterationRunResult, setIterationRunResult] = useState<NodeTracing[]>([])
|
||||
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
Node as WorkflowNode,
|
||||
} from '@/app/components/workflow/types'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { NULL_STRATEGY } from '@/app/components/workflow/nodes/_base/constants'
|
||||
import { Type } from '@/app/components/workflow/nodes/llm/types'
|
||||
import { BlockEnum, EditionType, isPromptMessageContext, PromptRole, VarType } from '@/app/components/workflow/types'
|
||||
@@ -441,7 +442,11 @@ export function useMixedVariableExtractor({
|
||||
detectAgentFromText: payload.detectAgentFromText,
|
||||
})
|
||||
}
|
||||
catch {
|
||||
catch (error) {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: error as string,
|
||||
})
|
||||
}
|
||||
}, [applyNestedNodeGraphData, configsMap?.flowId, configsMap?.flowType, paramKey, resolveNestedNodeParameterSchema, toolNodeId])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user