diff --git a/web/app/components/rag-pipeline/components/input-field/field-list/index.tsx b/web/app/components/rag-pipeline/components/input-field/field-list/index.tsx index fb2e61caf9..5d2efecb3f 100644 --- a/web/app/components/rag-pipeline/components/input-field/field-list/index.tsx +++ b/web/app/components/rag-pipeline/components/input-field/field-list/index.tsx @@ -2,12 +2,14 @@ import type { InputVar } from '@/app/components/workflow/types' import { RiAddLine } from '@remixicon/react' import FieldItem from './field-item' import cn from '@/utils/classnames' -import { useState } from 'react' +import { useCallback, useMemo, useState } from 'react' import InputFieldEditor from '../editor' +import { ReactSortable } from 'react-sortablejs' type FieldListProps = { LabelRightContent: React.ReactNode - inputFields?: InputVar[] + inputFields: InputVar[] + handleInputFieldsChange: (value: InputVar[]) => void readonly?: boolean labelClassName?: string } @@ -15,22 +17,44 @@ type FieldListProps = { const FieldList = ({ LabelRightContent, inputFields, + handleInputFieldsChange, readonly, labelClassName, }: FieldListProps) => { const [showInputFieldEditor, setShowInputFieldEditor] = useState(false) + const optionList = useMemo(() => { + return inputFields.map((content, index) => { + return ({ + id: index, + name: content.variable, + }) + }) + }, [inputFields]) + + const handleListSortChange = useCallback((list: Array<{ id: number, name: string }>) => { + const newInputFields = list.map((item) => { + return inputFields.find(field => field.variable === item.name) + }) + handleInputFieldsChange(newInputFields as InputVar[]) + }, [handleInputFieldsChange, inputFields]) + + const handleRemoveField = useCallback((index: number) => { + const newInputFields = inputFields.filter((_, i) => i !== index) + handleInputFieldsChange(newInputFields) + }, [handleInputFieldsChange, inputFields]) + const handleAddField = () => { setShowInputFieldEditor(true) } - const handleEditField = (index: number) => { + const handleEditField = useCallback((index: number) => { setShowInputFieldEditor(true) - } + }, []) - const handleCloseEditor = () => { + const handleCloseEditor = useCallback(() => { setShowInputFieldEditor(false) - } + }, []) return (
@@ -48,19 +72,25 @@ const FieldList = ({
-
+ handleListSortChange(list)} + handle='.handle' + ghostClass="opacity-50" + animation={150} + disabled={readonly} + > {inputFields?.map((item, index) => ( { - // Handle remove action - }} + onRemove={handleRemoveField.bind(null, index)} onClickEdit={handleEditField.bind(null, index)} /> ))} -
+ {showInputFieldEditor && ( } const InputFieldDialog = ({ readonly = false, + initialInputFieldsMap, }: InputFieldDialogProps) => { const showInputFieldDialog = useStore(state => state.showInputFieldDialog) const setShowInputFieldDialog = useStore(state => state.setShowInputFieldDialog) + // TODO: delete mock data + const [inputFieldsMap, setInputFieldsMap] = useState(initialInputFieldsMap || { + jina: [{ + variable: 'name', + label: 'name', + type: InputVarType.textInput, + required: true, + max_length: 12, + }, { + variable: 'num', + label: 'num', + type: InputVarType.number, + required: true, + }], + firecrawl: [{ + variable: 'name', + label: 'name', + type: InputVarType.textInput, + required: true, + max_length: 12, + }], + shared: [{ + variable: 'name', + label: 'name', + type: InputVarType.textInput, + required: true, + max_length: 12, + }], + }) + + const updateInputFields = useCallback((key: string, value: InputVar[]) => { + setInputFieldsMap(prev => ({ + ...prev, + [key]: value, + })) + }, []) const closePanel = useCallback(() => { setShowInputFieldDialog?.(false) @@ -58,20 +98,10 @@ const InputFieldDialog = ({ Jina Reader )} - inputFields={[{ - variable: 'name', - label: 'name', - type: InputVarType.textInput, - required: true, - max_length: 12, - }, { - variable: 'num', - label: 'num', - type: InputVarType.number, - required: true, - }]} + inputFields={inputFieldsMap.jina} readonly={readonly} labelClassName='pt-2 pb-1' + handleInputFieldsChange={updateInputFields.bind(null, 'jina')} /> {/* Firecrawl Field List */} Firecrawl )} - inputFields={[{ - variable: 'name', - label: 'name', - type: InputVarType.textInput, - required: true, - max_length: 12, - }]} + inputFields={inputFieldsMap.firecrawl} readonly={readonly} labelClassName='pt-2 pb-1' + handleInputFieldsChange={updateInputFields.bind(null, 'firecrawl')} /> {/* Shared Inputs */} )} - inputFields={[{ - variable: 'name', - label: 'name', - type: InputVarType.textInput, - required: true, - max_length: 12, - }]} + inputFields={inputFieldsMap.shared} readonly={readonly} labelClassName='pt-1 pb-2' + handleInputFieldsChange={updateInputFields.bind(null, 'shared')} />