From 66fd60bc6f4a273826c9835350d5e7c89e06ae22 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 20 Mar 2024 21:47:29 +0800 Subject: [PATCH] fix: var objects sorts change --- .../components/variable/output-var-list.tsx | 29 +++++++++-------- .../components/variable/var-type-picker.tsx | 4 +-- .../nodes/_base/hooks/use-output-var-list.ts | 31 ++++++++++++++++--- .../components/workflow/nodes/code/panel.tsx | 5 +++ .../workflow/nodes/code/use-config.ts | 19 ++++++++++-- 5 files changed, 66 insertions(+), 22 deletions(-) diff --git a/web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx b/web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx index 6dc3b4e42a..1316ec2bbc 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx @@ -10,31 +10,37 @@ import type { VarType } from '@/app/components/workflow/types' type Props = { readonly: boolean outputs: OutputVar - onChange: (payload: OutputVar) => void + outputKeyOrders: string[] + onChange: (payload: OutputVar, changedIndex?: number, newKey?: string) => void + onRemove: (index: number) => void } const OutputVarList: FC = ({ readonly, outputs, + outputKeyOrders, onChange, + onRemove, }) => { - const list = (Object.keys(outputs)).map((key) => { + const list = outputKeyOrders.map((key) => { return { variable: key, - variable_type: outputs[key].type, + variable_type: outputs[key]?.type, } }) const handleVarNameChange = useCallback((index: number) => { return (e: React.ChangeEvent) => { const oldKey = list[index].variable + const newKey = e.target.value + const newOutputs = produce(outputs, (draft) => { - const newKey = e.target.value draft[newKey] = draft[oldKey] delete draft[oldKey] }) - onChange(newOutputs) + onChange(newOutputs, index, newKey) } - }, [list, onChange]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [list, onChange, outputs, outputKeyOrders]) const handleVarTypeChange = useCallback((index: number) => { return (value: string) => { @@ -44,17 +50,14 @@ const OutputVarList: FC = ({ }) onChange(newOutputs) } - }, [list, onChange]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [list, onChange, outputs, outputKeyOrders]) const handleVarRemove = useCallback((index: number) => { return () => { - const key = list[index].variable - const newOutputs = produce(outputs, (draft) => { - delete draft[key] - }) - onChange(newOutputs) + onRemove(index) } - }, [list, onChange]) + }, [onRemove]) return (
diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-type-picker.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-type-picker.tsx index bb99d1ff1c..1f70b1f6e1 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-type-picker.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-type-picker.tsx @@ -44,8 +44,8 @@ const VarReferencePicker: FC = ({ > setOpen(!open)} className='w-[120px] cursor-pointer'>
-
{value}
- +
{value}
+
= { inputs: T setInputs: (newInputs: T) => void varKey?: string + outputKeyOrders: string[] + onOutputKeyOrdersChange: (newOutputKeyOrders: string[]) => void } function useOutputVarList({ inputs, setInputs, varKey = 'outputs', + outputKeyOrders = [], + onOutputKeyOrdersChange, }: Params) { - const handleVarsChange = useCallback((newVars: OutputVar) => { + const handleVarsChange = useCallback((newVars: OutputVar, changedIndex?: number, newKey?: string) => { const newInputs = produce(inputs, (draft: any) => { draft[varKey] = newVars }) setInputs(newInputs) - }, [inputs, setInputs, varKey]) + + if (changedIndex !== undefined) { + const newOutputKeyOrders = produce(outputKeyOrders, (draft) => { + draft[changedIndex] = newKey! + }) + onOutputKeyOrdersChange(newOutputKeyOrders) + } + }, [inputs, setInputs, varKey, outputKeyOrders, onOutputKeyOrdersChange]) const handleAddVariable = useCallback(() => { + const newKey = `var-${Object.keys((inputs as any)[varKey]).length + 1}` const newInputs = produce(inputs, (draft: any) => { draft[varKey] = { ...draft[varKey], - [`var-${Object.keys(draft[varKey]).length + 1}`]: { + [newKey]: { type: VarType.string, children: null, }, } }) setInputs(newInputs) - }, [inputs, setInputs, varKey]) + onOutputKeyOrdersChange([...outputKeyOrders, newKey]) + }, [inputs, setInputs, varKey, outputKeyOrders, onOutputKeyOrdersChange]) + + const handleRemoveVariable = useCallback((index: number) => { + const key = outputKeyOrders[index] + const newInputs = produce(inputs, (draft: any) => { + delete draft[varKey][key] + }) + setInputs(newInputs) + onOutputKeyOrdersChange(outputKeyOrders.filter((_, i) => i !== index)) + }, [inputs, setInputs, varKey, outputKeyOrders, onOutputKeyOrdersChange]) return { handleVarsChange, handleAddVariable, + handleRemoveVariable, } } diff --git a/web/app/components/workflow/nodes/code/panel.tsx b/web/app/components/workflow/nodes/code/panel.tsx index 88a533a17f..087f3cd758 100644 --- a/web/app/components/workflow/nodes/code/panel.tsx +++ b/web/app/components/workflow/nodes/code/panel.tsx @@ -35,8 +35,10 @@ const Panel: FC> = ({ const { readOnly, inputs, + outputKeyOrders, handleVarListChange, handleAddVariable, + handleRemoveVariable, handleCodeChange, handleCodeLanguageChange, handleVarsChange, @@ -94,10 +96,13 @@ const Panel: FC> = ({ } > +
diff --git a/web/app/components/workflow/nodes/code/use-config.ts b/web/app/components/workflow/nodes/code/use-config.ts index 826ad74ddc..85f0948aff 100644 --- a/web/app/components/workflow/nodes/code/use-config.ts +++ b/web/app/components/workflow/nodes/code/use-config.ts @@ -5,7 +5,7 @@ import useOutputVarList from '../_base/hooks/use-output-var-list' import { BlockEnum, VarType } from '../../types' import type { Var } from '../../types' import { useStore } from '../../store' -import type { CodeNodeType } from './types' +import type { CodeNodeType, OutputVar } from './types' import { CodeLanguage } from './types' import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' import useOneStepRun from '@/app/components/workflow/nodes/_base/hooks/use-one-step-run' @@ -41,9 +41,17 @@ const useConfig = (id: string, payload: CodeNodeType) => { setInputs, }) + const [outputKeyOrders, setOutputKeyOrders] = useState([]) + const syncOutputKeyOrders = useCallback((outputs: OutputVar) => { + setOutputKeyOrders(Object.keys(outputs)) + }, []) useEffect(() => { - if (inputs.code) + if (inputs.code) { + if (inputs.outputs && Object.keys(inputs.outputs).length > 0) + syncOutputKeyOrders(inputs.outputs) + return + } const isReady = defaultConfig && Object.keys(defaultConfig).length > 0 if (isReady) { @@ -51,6 +59,7 @@ const useConfig = (id: string, payload: CodeNodeType) => { ...inputs, ...defaultConfig, }) + syncOutputKeyOrders(defaultConfig.outputs) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultConfig]) @@ -76,9 +85,11 @@ const useConfig = (id: string, payload: CodeNodeType) => { setInputs(newInputs) }, [allLanguageDefault, inputs, setInputs]) - const { handleVarsChange, handleAddVariable: handleAddOutputVariable } = useOutputVarList({ + const { handleVarsChange, handleAddVariable: handleAddOutputVariable, handleRemoveVariable } = useOutputVarList({ inputs, setInputs, + outputKeyOrders, + onOutputKeyOrdersChange: setOutputKeyOrders, }) const filterVar = useCallback((varPayload: Var) => { @@ -121,8 +132,10 @@ const useConfig = (id: string, payload: CodeNodeType) => { return { readOnly, inputs, + outputKeyOrders, handleVarListChange, handleAddVariable, + handleRemoveVariable, handleCodeChange, handleCodeLanguageChange, handleVarsChange,