fix(workflow): use correct field ID in KB metadata filter selection (#34149)

Co-authored-by: 非法操作 <hjlarry@163.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
shawnYJ 2026-05-07 10:21:30 +08:00 committed by GitHub
parent 3ebb449d25
commit 376c43e5ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 76 additions and 32 deletions

View File

@ -4194,11 +4194,6 @@
"count": 1
}
},
"web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-value-method.tsx": {
"no-restricted-imports": {
"count": 1
}
},
"web/app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/index.tsx": {
"no-restricted-imports": {
"count": 1

View File

@ -19,6 +19,7 @@ import { BlockEnum, VarType } from '../../../types'
import AddDataset from '../components/add-dataset'
import DatasetItem from '../components/dataset-item'
import DatasetList from '../components/dataset-list'
import AddCondition from '../components/metadata/add-condition'
import ConditionCommonVariableSelector from '../components/metadata/condition-list/condition-common-variable-selector'
import ConditionDate from '../components/metadata/condition-list/condition-date'
import ConditionItem from '../components/metadata/condition-list/condition-item'
@ -462,6 +463,29 @@ describe('knowledge-retrieval path', () => {
expect(screen.getByText('metadata-panel')).toBeInTheDocument()
})
it('should call handleAddCondition with the correct metadata item when clicking any part of the row', async () => {
const user = userEvent.setup()
const handleAddCondition = vi.fn()
const permissionMetadata = createMetadata({ id: 'meta-perm', name: 'permission', type: MetadataFilteringVariableType.string })
const topicMetadata = createMetadata({ id: 'meta-topic', name: 'topic', type: MetadataFilteringVariableType.string })
render(
<AddCondition
metadataList={[permissionMetadata, topicMetadata]}
handleAddCondition={handleAddCondition}
/>,
)
await user.click(screen.getByRole('button', { name: /workflow.nodes.knowledgeRetrieval.metadata.panel.add/i }))
await user.click(screen.getAllByText('string', { selector: 'div.shrink-0' })[0]!)
expect(handleAddCondition).toHaveBeenCalledTimes(1)
expect(handleAddCondition).toHaveBeenCalledWith(expect.objectContaining({
id: 'meta-perm',
name: 'permission',
}))
})
it('should render automatic and manual metadata filter states', async () => {
const user = userEvent.setup()
const baseProps: MetadataShape = {
@ -591,6 +615,24 @@ describe('knowledge-retrieval path', () => {
expect(onUpdateCondition).toHaveBeenCalledWith('condition-1', expect.objectContaining({ value: 'updated-agent' }))
expect(onRemoveCondition).toHaveBeenCalledWith('condition-1')
})
it('should resolve built-in metadata fields by name because their ids are shared', () => {
render(
<ConditionItem
metadataList={[
createMetadata({ id: 'built-in', name: 'document_name' }),
createMetadata({ id: 'built-in', name: 'uploader' }),
]}
condition={createCondition({
metadata_id: 'built-in',
name: 'uploader',
})}
/>,
)
expect(screen.getByText('uploader')).toBeInTheDocument()
expect(screen.queryByText('document_name')).not.toBeInTheDocument()
})
})
describe('Node rendering', () => {

View File

@ -65,6 +65,7 @@ const AddCondition = ({
<div
key={metadata.name}
className="flex h-6 cursor-pointer items-center rounded-md px-3 system-sm-medium text-text-secondary hover:bg-state-base-hover"
onClick={() => handleAddConditionWrapped(metadata)}
>
<div className="mr-1 p-px">
<MetadataIcon type={metadata.type} />
@ -72,7 +73,6 @@ const AddCondition = ({
<div
className="grow truncate"
title={metadata.name}
onClick={() => handleAddConditionWrapped(metadata)}
>
{metadata.name}
</div>

View File

@ -62,13 +62,16 @@ const ConditionItem = ({
}, [onRemoveCondition, condition.id])
const currentMetadata = useMemo(() => {
// Try to match by metadata_id first (reliable reference)
if (condition.metadata_id) {
const found = metadataList.find(metadata => metadata.id === condition.metadata_id)
if (found)
return found
const foundByIdAndName = metadataList.find(metadata => metadata.id === condition.metadata_id && metadata.name === condition.name)
if (foundByIdAndName)
return foundByIdAndName
const foundById = metadataList.filter(metadata => metadata.id === condition.metadata_id)
if (foundById.length === 1)
return foundById[0]
}
// Fallback to name matching for backward compatibility with old conditions
return metadataList.find(metadata => metadata.name === condition.name)
}, [metadataList, condition.metadata_id, condition.name])

View File

@ -1,13 +1,13 @@
import { Button } from '@langgenius/dify-ui/button'
import { cn } from '@langgenius/dify-ui/cn'
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@langgenius/dify-ui/popover'
import { RiArrowDownSLine } from '@remixicon/react'
import { capitalize } from 'es-toolkit/string'
import { useState } from 'react'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
export type ConditionValueMethodProps = {
valueMethod?: string
@ -24,23 +24,27 @@ const ConditionValueMethod = ({
const [open, setOpen] = useState(false)
return (
<PortalToFollowElem
<Popover
open={open}
onOpenChange={setOpen}
placement="bottom-start"
offset={{ mainAxis: 4, crossAxis: 0 }}
>
<PortalToFollowElemTrigger asChild onClick={() => setOpen(v => !v)}>
<Button
className="shrink-0"
variant="ghost"
size="small"
>
{capitalize(valueMethod)}
<RiArrowDownSLine className="ml-px h-3.5 w-3.5" />
</Button>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className="z-1000">
<PopoverTrigger
render={(
<Button
className="shrink-0"
variant="ghost"
size="small"
>
{capitalize(valueMethod)}
<RiArrowDownSLine className="ml-px h-3.5 w-3.5" />
</Button>
)}
/>
<PopoverContent
placement="bottom-start"
sideOffset={4}
popupClassName="border-none bg-transparent p-0 shadow-none backdrop-blur-none"
>
<div className="w-[112px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-1 shadow-lg">
{
options.map(option => (
@ -63,8 +67,8 @@ const ConditionValueMethod = ({
))
}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
</PopoverContent>
</Popover>
)
}