diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx index 9eb34ac7f..b1a8d52a0 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React, { useCallback } from 'react' +import React, { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import produce from 'immer' import RemoveButton from '../remove-button' @@ -10,6 +10,10 @@ import type { ValueSelector, Var, Variable } from '@/app/components/workflow/typ import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var' import Toast from '@/app/components/base/toast' +import { ReactSortable } from 'react-sortablejs' +import { v4 as uuid4 } from 'uuid' +import { RiDraggable } from '@remixicon/react' +import cn from '@/utils/classnames' type Props = { nodeId: string @@ -36,6 +40,14 @@ const VarList: FC = ({ }) => { const { t } = useTranslation() + const listWithIds = useMemo(() => list.map((item) => { + const id = uuid4() + return { + id, + variable: { ...item }, + } + }), [list]) + const handleVarNameChange = useCallback((index: number) => { return (e: React.ChangeEvent) => { replaceSpaceWithUnderscreInVarNameInput(e.target) @@ -105,36 +117,56 @@ const VarList: FC = ({ } }, [list, onChange]) + const varCount = list.length + return ( -
- {list.map((item, index) => ( -
- - - {!readonly && ( - - )} -
- ))} -
+ { onChange(list.map(item => item.variable)) }} + handle='.handle' + ghostClass='opacity-50' + animation={150} + > + {list.map((variable, index) => { + const canDrag = (() => { + if (readonly) + return false + return varCount > 1 + })() + return ( +
+ + + {!readonly && ( + + )} + {canDrag &&
+ ) + })} +
) } export default React.memo(VarList)