fix: var reference picker can not choose sub vars (#35732)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Joel
2026-04-30 16:33:29 +08:00
committed by GitHub
parent 5cf741895f
commit 0ca339103f
5 changed files with 54 additions and 13 deletions

View File

@@ -1744,11 +1744,6 @@
"count": 4
}
},
"web/app/components/base/prompt-editor/plugins/component-picker-block/index.tsx": {
"ts/no-explicit-any": {
"count": 1
}
},
"web/app/components/base/prompt-editor/plugins/component-picker-block/menu.tsx": {
"erasable-syntax-only/parameter-properties": {
"count": 1

View File

@@ -29,6 +29,7 @@ import {
} from 'lexical'
import * as React from 'react'
import { GeneratorType } from '@/app/components/app/configuration/config/automatic/types'
import { VAR_REFERENCE_CHILD_POPUP_CLASS_NAME } from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars'
import { VarType } from '@/app/components/workflow/types'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import { EventEmitterContextProvider } from '@/context/event-emitter-provider'
@@ -928,5 +929,46 @@ describe('ComponentPicker (component-picker-block/index.tsx)', () => {
vi.useRealTimers()
})
it('does not hide the menu when focus moves into a variable child popup', async () => {
const captures: Captures = { editor: null, eventEmitter: null }
render((
<MinimalEditor
triggerString="/"
workflowVariableBlock={makeWorkflowVariableBlock({}, [
makeWorkflowVarNode('node-1', 'Node 1', [
makeWorkflowNodeVar('payload', VarType.object, [makeWorkflowNodeVar('child', VarType.string)]),
]),
])}
captures={captures}
/>
))
const editor = await waitForEditor(captures)
await setEditorText(editor, '/', true)
expect(await screen.findByText('payload')).toBeInTheDocument()
vi.useFakeTimers()
const popupTarget = document.createElement('button')
const popup = document.createElement('div')
popup.classList.add(VAR_REFERENCE_CHILD_POPUP_CLASS_NAME)
popup.appendChild(popupTarget)
document.body.appendChild(popup)
act(() => {
editor.dispatchCommand(BLUR_COMMAND, new FocusEvent('blur-sm', { relatedTarget: popupTarget }))
})
act(() => {
vi.advanceTimersByTime(200)
})
expect(screen.queryByText('payload')).toBeInTheDocument()
popup.remove()
vi.useRealTimers()
})
})
})

View File

@@ -14,6 +14,7 @@ import type {
WorkflowVariableBlockType,
} from '../../types'
import type { PickerBlockMenuOption } from './menu'
import type { EventEmitterValue } from '@/context/event-emitter'
import {
flip,
offset,
@@ -39,7 +40,7 @@ import {
} from 'react'
import ReactDOM from 'react-dom'
import { GeneratorType } from '@/app/components/app/configuration/config/automatic/types'
import VarReferenceVars from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars'
import VarReferenceVars, { VAR_REFERENCE_CHILD_POPUP_CLASS_NAME } from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import { useBasicTypeaheadTriggerMatch } from '../../hooks'
import { $splitNodeContainingQuery } from '../../utils'
@@ -119,7 +120,9 @@ const ComponentPicker = ({
(event) => {
clearBlurTimer()
const target = event?.relatedTarget as HTMLElement
if (!target?.classList?.contains('var-search-input'))
const isVariableMenuTarget = target?.classList?.contains('var-search-input')
|| target?.closest?.(`.${VAR_REFERENCE_CHILD_POPUP_CLASS_NAME}`)
if (!isVariableMenuTarget)
blurTimerRef.current = setTimeout(() => setBlurHidden(true), 200)
return false
},
@@ -143,8 +146,8 @@ const ComponentPicker = ({
}
}, [editor, clearBlurTimer])
eventEmitter?.useSubscription((v: any) => {
if (v.type === INSERT_VARIABLE_VALUE_BLOCK_COMMAND)
eventEmitter?.useSubscription((v: EventEmitterValue) => {
if (typeof v !== 'string' && v.type === INSERT_VARIABLE_VALUE_BLOCK_COMMAND && typeof v.payload === 'string')
editor.dispatchCommand(INSERT_VARIABLE_VALUE_BLOCK_COMMAND, `{{${v.payload}}}`)
})
@@ -303,7 +306,7 @@ const ComponentPicker = ({
}
</>
)
}, [blurHidden, allFlattenOptions.length, workflowVariableBlock?.show, floatingStyles, isPositioned, refs, workflowVariableOptions, isSupportFileVar, handleClose, currentBlock?.generatorType, handleSelectWorkflowVariable, queryString, workflowVariableBlock?.showManageInputField, workflowVariableBlock?.onManageInputField])
}, [blurHidden, allFlattenOptions.length, workflowVariableBlock?.show, floatingStyles, isPositioned, refs, workflowVariableOptions, isSupportFileVar, handleClose, currentBlock?.generatorType, handleSelectWorkflowVariable, queryString, triggerString, workflowVariableBlock?.showManageInputField, workflowVariableBlock?.onManageInputField])
return (
<LexicalTypeaheadMenuPlugin

View File

@@ -43,7 +43,7 @@ const Field: FC<Props> = ({
disabled={depth !== MAX_DEPTH + 1}
render={(
<div
className={cn('flex items-center justify-between rounded-md pr-2', !readonly && 'hover:bg-state-base-hover', depth !== MAX_DEPTH + 1 && 'cursor-pointer')}
className={cn('flex items-center justify-between rounded-md pr-2 outline-none focus:outline-none focus-visible:outline-none', !readonly && 'hover:bg-state-base-hover', depth !== MAX_DEPTH + 1 && 'cursor-pointer')}
onMouseDown={() => !readonly && onSelect?.([...valueSelector, name])}
>
<div className="flex grow items-stretch">

View File

@@ -29,6 +29,7 @@ import {
} from './var-reference-vars.helpers'
const VAR_SEARCH_INPUT_CLASS_NAME = 'var-search-input'
export const VAR_REFERENCE_CHILD_POPUP_CLASS_NAME = 'var-reference-vars-child-popup'
const resolveValueSelector = ({
itemData,
@@ -210,7 +211,7 @@ const Item: FC<ItemProps> = ({
className={cn(
(isObj || isStructureOutput) ? 'pr-1' : 'pr-[18px]',
(isHovering || isSelected) && ((isObj || isStructureOutput) ? 'bg-components-panel-on-panel-item-bg-hover' : 'bg-state-base-hover'),
'relative flex h-6 w-full cursor-pointer items-center rounded-md pl-3',
'relative flex h-6 w-full cursor-pointer items-center rounded-md pl-3 outline-none focus:outline-none focus-visible:outline-none',
className,
)}
data-selected={isSelected ? 'true' : 'false'}
@@ -263,7 +264,7 @@ const Item: FC<ItemProps> = ({
<PopoverContent
placement="left-start"
sideOffset={0}
popupClassName="border-none bg-transparent p-0 shadow-none backdrop-blur-none"
popupClassName={cn(VAR_REFERENCE_CHILD_POPUP_CLASS_NAME, 'border-none bg-transparent p-0 shadow-none backdrop-blur-none')}
positionerProps={{
style: {
zIndex: zIndex || 100,