mirror of
https://github.com/langgenius/dify.git
synced 2026-05-13 00:33:37 +08:00
fix(web): dynamic select display
This commit is contained in:
parent
17759c0b80
commit
998201f6e3
@ -142,6 +142,26 @@ describe('variable-in-markdown', () => {
|
||||
expect(screen.getByText('Approved')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render variable source information for dynamic select inputs', () => {
|
||||
render(
|
||||
<Note
|
||||
input={{
|
||||
type: InputVarType.select,
|
||||
output_variable_name: 'approval',
|
||||
option_source: {
|
||||
type: 'variable',
|
||||
selector: ['node-1', 'options'],
|
||||
value: [],
|
||||
},
|
||||
}}
|
||||
nodeName={nodeId => nodeId === 'node-1' ? 'Start Node' : nodeId}
|
||||
/>,
|
||||
)
|
||||
|
||||
expect(screen.getByTestId('human-input-note-select-preview')).toBeInTheDocument()
|
||||
expect(screen.getByText('{{Start Node/options}}')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should open the select preview and show option items', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/* eslint-disable react-refresh/only-export-components */
|
||||
import type { ReactNode } from 'react'
|
||||
import type { FormInputItem } from '../types'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { Select, SelectContent, SelectItem, SelectItemIndicator, SelectItemText, SelectTrigger } from '@langgenius/dify-ui/select'
|
||||
@ -93,6 +94,17 @@ const formatVariablePath = (path: string) => {
|
||||
.replace('#}}', '}}')
|
||||
}
|
||||
|
||||
const sourceToVariablePath = (
|
||||
source: { selector: string[] },
|
||||
nodeName: (nodeId: string) => string,
|
||||
) => {
|
||||
if (!source.selector.length)
|
||||
return ''
|
||||
|
||||
const path = `{{#${source.selector.join('.')}#}}`
|
||||
return replaceNodeIdsWithNames(path, nodeName)
|
||||
}
|
||||
|
||||
export function rehypeVariable() {
|
||||
return (tree: MarkdownNode) => {
|
||||
visitTextNodes(tree, (value) => {
|
||||
@ -138,14 +150,14 @@ export const Variable: React.FC<{ path: string }> = ({ path }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const SelectPreview: React.FC<{ label: string, options: string[] }> = ({ label, options }) => {
|
||||
const SelectPreview: React.FC<{ label: string, options: string[], triggerContent?: ReactNode }> = ({ label, options, triggerContent }) => {
|
||||
const [value, setValue] = React.useState(options[0] || label)
|
||||
|
||||
return (
|
||||
<div data-testid="human-input-note-select-preview" className="my-3">
|
||||
<Select value={value} onValueChange={nextValue => nextValue && setValue(nextValue)}>
|
||||
<SelectTrigger size="large" className="w-full rounded-[10px]" aria-label="human-input-note-select">
|
||||
{value}
|
||||
{triggerContent || value}
|
||||
</SelectTrigger>
|
||||
<SelectContent listClassName="max-h-[140px] overflow-y-auto">
|
||||
{options.map(option => (
|
||||
@ -202,11 +214,20 @@ export const Note: React.FC<{ input: FormInputItem, nodeName: (nodeId: string) =
|
||||
const { t } = useTranslation()
|
||||
if (isSelectFormInput(input)) {
|
||||
const isVariable = input.option_source.type === 'variable'
|
||||
const variablePath = isVariable
|
||||
? sourceToVariablePath(input.option_source, nodeName)
|
||||
: ''
|
||||
const label = isVariable
|
||||
? t('nodes.humanInput.insertInputField.variable', { ns: 'workflow' })
|
||||
? variablePath || t('nodes.humanInput.insertInputField.variable', { ns: 'workflow' })
|
||||
: input.option_source.value[0] || t('variableConfig.select', { ns: 'appDebug' })
|
||||
const options = isVariable ? [label] : input.option_source.value
|
||||
return <SelectPreview label={label} options={options} />
|
||||
return (
|
||||
<SelectPreview
|
||||
label={label}
|
||||
options={options}
|
||||
triggerContent={variablePath ? <Variable path={variablePath} /> : undefined}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (isFileFormInput(input)) {
|
||||
@ -218,8 +239,7 @@ export const Note: React.FC<{ input: FormInputItem, nodeName: (nodeId: string) =
|
||||
}
|
||||
|
||||
const isVariable = input.default.type === 'variable'
|
||||
const path = `{{#${input.default.selector.join('.')}#}}`
|
||||
const newPath = path ? replaceNodeIdsWithNames(path, nodeName) : path
|
||||
const newPath = sourceToVariablePath(input.default, nodeName)
|
||||
return (
|
||||
<div className="my-3 rounded-[10px] bg-components-input-bg-normal px-2.5 py-2">
|
||||
{isVariable ? <Variable path={newPath} /> : <span>{input.default.value}</span>}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user