diff --git a/web/app/components/workflow/nodes/http/__tests__/integration.spec.tsx b/web/app/components/workflow/nodes/http/__tests__/integration.spec.tsx index 9fb94dece0..99d240c6d6 100644 --- a/web/app/components/workflow/nodes/http/__tests__/integration.spec.tsx +++ b/web/app/components/workflow/nodes/http/__tests__/integration.spec.tsx @@ -501,6 +501,34 @@ describe('http path', () => { expect(onChange).toHaveBeenCalled() }) + it('should only append a new key-value row after the last value field receives content', () => { + const onChange = vi.fn() + const onRemove = vi.fn() + const onAdd = vi.fn() + render( + , + ) + + const valueInput = screen.getAllByPlaceholderText('workflow.nodes.http.insertVarPlaceholder')[1]! + + fireEvent.click(valueInput) + expect(onAdd).not.toHaveBeenCalled() + + fireEvent.change(valueInput, { target: { value: 'alice' } }) + expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ value: 'alice' })) + expect(onAdd).toHaveBeenCalledTimes(1) + }) + it('should edit key-only rows and select file payload rows', async () => { const user = userEvent.setup() const onChange = vi.fn() diff --git a/web/app/components/workflow/nodes/http/components/key-value/key-value-edit/item.tsx b/web/app/components/workflow/nodes/http/components/key-value/key-value-edit/item.tsx index 0d6c64373d..51d887d344 100644 --- a/web/app/components/workflow/nodes/http/components/key-value/key-value-edit/item.tsx +++ b/web/app/components/workflow/nodes/http/components/key-value/key-value-edit/item.tsx @@ -47,20 +47,37 @@ const KeyValueItem: FC = ({ insertVarTipToLeft, }) => { const { t } = useTranslation() + const hasValuePayload = payload.type === 'file' + ? !!payload.file?.length + : !!payload.value const handleChange = useCallback((key: string) => { return (value: string | ValueSelector) => { + const shouldAddNextItem = isLastItem + && ( + (key === 'value' && !payload.value && !!value) + || (key === 'file' && (!payload.file || payload.file.length === 0) && Array.isArray(value) && value.length > 0) + ) + const newPayload = produce(payload, (draft: any) => { draft[key] = value }) onChange(newPayload) + + if (shouldAddNextItem) + onAdd() } - }, [onChange, payload]) + }, [isLastItem, onAdd, onChange, payload]) const filterOnlyFileVariable = (varPayload: Var) => { return [VarType.file, VarType.arrayFile].includes(varPayload.type) } + const handleValueContainerClick = useCallback(() => { + if (isLastItem && hasValuePayload) + onAdd() + }, [hasValuePayload, isLastItem, onAdd]) + return ( // group class name is for hover row show remove button @@ -102,7 +119,10 @@ const KeyValueItem: FC = ({ /> )} - isLastItem && onAdd()}> + {(isSupportFile && payload.type === 'file') ? (