From 5153068a64604eb99edca263c3d6b62dc05affd7 Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 22 Feb 2024 16:17:27 +0800 Subject: [PATCH] feat: start var list --- .../nodes/start/components/var-item.tsx | 59 +++++++++++++++++++ .../nodes/start/components/var-list.tsx | 50 ++++++++++++++++ .../components/workflow/nodes/start/panel.tsx | 20 ++++++- .../workflow/nodes/start/use-config.ts | 19 +++++- web/i18n/lang/workflow.en.ts | 1 + 5 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 web/app/components/workflow/nodes/start/components/var-item.tsx create mode 100644 web/app/components/workflow/nodes/start/components/var-list.tsx diff --git a/web/app/components/workflow/nodes/start/components/var-item.tsx b/web/app/components/workflow/nodes/start/components/var-item.tsx new file mode 100644 index 0000000000..da646f3b2b --- /dev/null +++ b/web/app/components/workflow/nodes/start/components/var-item.tsx @@ -0,0 +1,59 @@ +'use client' +import type { FC } from 'react' +import React, { useRef } from 'react' +import { useHover } from 'ahooks' +import { useTranslation } from 'react-i18next' +import InputVarTypeIcon from '../../_base/components/input-var-type-icon' +import type { InputVar } from '@/app/components/workflow/types' +import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' +import { Edit03 } from '@/app/components/base/icons/src/vender/solid/general' +import { Trash03 } from '@/app/components/base/icons/src/vender/line/general' + +type Props = { + readonly: boolean + payload: InputVar + onChange: (item: InputVar) => void + onRemove: () => void +} + +const VarItem: FC = ({ + readonly, + payload, +}) => { + const { t } = useTranslation() + + const ref = useRef(null) + const isHovering = useHover(ref) + return ( +
+
+ +
{payload.variable}
+
ยท
+
{payload.label}
+
+
+ {!isHovering + ? ( + <> + {payload.required && ( +
{t('workflow.nodes.start.required')}
+ )} + + + ) + : (!readonly && ( + <> +
+ +
+
+ +
+ + ))} +
+
+ ) +} +export default React.memo(VarItem) diff --git a/web/app/components/workflow/nodes/start/components/var-list.tsx b/web/app/components/workflow/nodes/start/components/var-list.tsx new file mode 100644 index 0000000000..033da3da35 --- /dev/null +++ b/web/app/components/workflow/nodes/start/components/var-list.tsx @@ -0,0 +1,50 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import produce from 'immer' +import VarItem from './var-item' +import type { InputVar } from '@/app/components/workflow/types' +type Props = { + readonly: boolean + list: InputVar[] + onChange: (list: InputVar[]) => void +} + +const VarList: FC = ({ + readonly, + list, + onChange, +}) => { + const handleVarNameChange = useCallback((index: number) => { + return (payload: InputVar) => { + const newList = produce(list, (draft) => { + draft[index] = payload + }) + onChange(newList) + } + }, [list, onChange]) + + const handleVarRemove = useCallback((index: number) => { + return () => { + const newList = produce(list, (draft) => { + draft.splice(index, 1) + }) + onChange(newList) + } + }, [list, onChange]) + + return ( +
+ {list.map((item, index) => ( + + ))} +
+ ) +} +export default React.memo(VarList) diff --git a/web/app/components/workflow/nodes/start/panel.tsx b/web/app/components/workflow/nodes/start/panel.tsx index 8ff6d148b9..6749c3852f 100644 --- a/web/app/components/workflow/nodes/start/panel.tsx +++ b/web/app/components/workflow/nodes/start/panel.tsx @@ -1,21 +1,37 @@ import type { FC } from 'react' import { useTranslation } from 'react-i18next' +import VarList from './components/var-list' +import useConfig from './use-config' +import { mockData } from './mock' import Split from '@/app/components/workflow/nodes/_base/components/split' import Field from '@/app/components/workflow/nodes/_base/components/field' import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars' +import AddButton from '@/app/components/base/button/add-button' const i18nPrefix = 'workflow.nodes.start' const Panel: FC = () => { const { t } = useTranslation() + const readOnly = false + const { + inputs, + handleVarListChange, + } = useConfig(mockData) return (
{ }} /> + } > - ss +
diff --git a/web/app/components/workflow/nodes/start/use-config.ts b/web/app/components/workflow/nodes/start/use-config.ts index 96da6e3cfa..3d96f418f7 100644 --- a/web/app/components/workflow/nodes/start/use-config.ts +++ b/web/app/components/workflow/nodes/start/use-config.ts @@ -1,11 +1,28 @@ -import { useState } from 'react' +import { useCallback, useState } from 'react' +import produce from 'immer' import type { StartNodeType } from './types' +import type { InputVar } from '@/app/components/workflow/types' const useConfig = (initInputs: StartNodeType) => { const [inputs, setInputs] = useState(initInputs) + const handleVarListChange = useCallback((newList: InputVar[]) => { + const newInputs = produce(inputs, (draft: any) => { + draft.variables = newList + }) + setInputs(newInputs) + }, [inputs, setInputs]) + + const handleAddVariable = useCallback((payload: InputVar) => { + const newInputs = produce(inputs, (draft: any) => { + draft.variables.push(payload) + }) + setInputs(newInputs) + }, [inputs, setInputs]) return { inputs, + handleVarListChange, + handleAddVariable, } } diff --git a/web/i18n/lang/workflow.en.ts b/web/i18n/lang/workflow.en.ts index 7b9b8f9258..ca8118b1a3 100644 --- a/web/i18n/lang/workflow.en.ts +++ b/web/i18n/lang/workflow.en.ts @@ -6,6 +6,7 @@ const translation = { }, start: { required: 'required', + inputField: 'Input Field', builtInVar: 'Built-in Variables', outputVars: { query: 'User input',