mirror of
https://github.com/langgenius/dify.git
synced 2026-09-07 18:36:02 +08:00
refactor(web): migrate loop variable constant inputs (#41901)
This commit is contained in:
parent
789cada297
commit
3e961dbb77
@ -4001,11 +4001,8 @@
|
||||
}
|
||||
},
|
||||
"web/app/components/workflow/nodes/loop/components/loop-variables/form-item.tsx": {
|
||||
"no-restricted-imports": {
|
||||
"count": 1
|
||||
},
|
||||
"typescript/no-explicit-any": {
|
||||
"count": 3
|
||||
"count": 2
|
||||
}
|
||||
},
|
||||
"web/app/components/workflow/nodes/loop/components/loop-variables/item.tsx": {
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
import type { LoopVariable } from '@/app/components/workflow/nodes/loop/types'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { useState } from 'react'
|
||||
import { ValueType, VarType } from '@/app/components/workflow/types'
|
||||
import FormItem from '../form-item'
|
||||
|
||||
describe('Loop variable constant input', () => {
|
||||
it('reports numeric edits and clearing as strings to the loop draft', async () => {
|
||||
const user = userEvent.setup()
|
||||
const onChange = vi.fn()
|
||||
function LoopDraft() {
|
||||
const [value, setValue] = useState('12')
|
||||
return (
|
||||
<FormItem
|
||||
nodeId="loop-node"
|
||||
item={{
|
||||
id: 'count',
|
||||
label: 'count',
|
||||
var_type: VarType.number,
|
||||
value_type: ValueType.constant,
|
||||
value,
|
||||
}}
|
||||
onChange={(nextValue) => {
|
||||
setValue(nextValue)
|
||||
onChange(nextValue)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
render(<LoopDraft />)
|
||||
|
||||
const input = screen.getByRole('spinbutton', { name: 'count' })
|
||||
await user.clear(input)
|
||||
expect(onChange).toHaveBeenLastCalledWith('')
|
||||
await user.type(input, '-3.5')
|
||||
expect(input).toHaveValue(-3.5)
|
||||
expect(onChange).toHaveBeenLastCalledWith('-3.5')
|
||||
})
|
||||
|
||||
it.each([
|
||||
[VarType.number, 'spinbutton'],
|
||||
[VarType.string, 'textbox'],
|
||||
] as const)('names an unnamed %s constant until its variable is named', (varType, role) => {
|
||||
const item: LoopVariable = {
|
||||
id: 'new-variable',
|
||||
label: '',
|
||||
var_type: varType,
|
||||
value_type: ValueType.constant,
|
||||
value: '',
|
||||
}
|
||||
const { rerender } = render(<FormItem nodeId="loop-node" item={item} onChange={vi.fn()} />)
|
||||
expect(
|
||||
screen.getByRole(role, { name: 'workflow.errorMsg.fields.variableValue' }),
|
||||
).toBeInTheDocument()
|
||||
|
||||
rerender(
|
||||
<FormItem nodeId="loop-node" item={{ ...item, label: 'counter' }} onChange={vi.fn()} />,
|
||||
)
|
||||
expect(screen.getByRole(role, { name: 'counter' })).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
@ -1,9 +1,9 @@
|
||||
import type { LoopVariable } from '@/app/components/workflow/nodes/loop/types'
|
||||
import type { Var } from '@/app/components/workflow/types'
|
||||
import { Input } from '@langgenius/dify-ui/input'
|
||||
import { Textarea } from '@langgenius/dify-ui/textarea'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/app/components/base/input'
|
||||
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
|
||||
import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker'
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
@ -26,17 +26,11 @@ type FormItemProps = {
|
||||
const FormItem = ({ nodeId, item, onChange }: FormItemProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { value_type, var_type, value } = item
|
||||
const valueLabel = item.label || t(($) => $['errorMsg.fields.variableValue'], { ns: 'workflow' })
|
||||
const normalizedVarValue = useMemo(() => {
|
||||
return Array.isArray(value) ? value : []
|
||||
}, [value])
|
||||
|
||||
const handleInputChange = useCallback(
|
||||
(e: any) => {
|
||||
onChange(e.target.value)
|
||||
},
|
||||
[onChange],
|
||||
)
|
||||
|
||||
const handleValueChange = useCallback(
|
||||
(value: string) => {
|
||||
onChange(value)
|
||||
@ -85,14 +79,21 @@ const FormItem = ({ nodeId, item, onChange }: FormItemProps) => {
|
||||
)}
|
||||
{value_type === ValueType.constant && var_type === VarType.string && (
|
||||
<Textarea
|
||||
aria-label={item.label}
|
||||
aria-label={valueLabel}
|
||||
value={value}
|
||||
onValueChange={handleValueChange}
|
||||
className="min-h-12 w-full"
|
||||
/>
|
||||
)}
|
||||
{value_type === ValueType.constant && var_type === VarType.number && (
|
||||
<Input type="number" value={value} onChange={handleInputChange} className="w-full" />
|
||||
<Input
|
||||
aria-label={valueLabel}
|
||||
type="number"
|
||||
value={value}
|
||||
onValueChange={handleValueChange}
|
||||
placeholder={t(($) => $['placeholder.input'], { ns: 'common' })}
|
||||
className="w-full"
|
||||
/>
|
||||
)}
|
||||
{value_type === ValueType.constant && var_type === VarType.boolean && (
|
||||
<BoolValue value={value} onChange={handleChange} />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user