diff --git a/web/app/components/workflow/nodes/_base/components/editor/type-selector.tsx b/web/app/components/workflow/nodes/_base/components/selector.tsx similarity index 53% rename from web/app/components/workflow/nodes/_base/components/editor/type-selector.tsx rename to web/app/components/workflow/nodes/_base/components/selector.tsx index 6fc6c295fe..799ca08a39 100644 --- a/web/app/components/workflow/nodes/_base/components/editor/type-selector.tsx +++ b/web/app/components/workflow/nodes/_base/components/selector.tsx @@ -4,24 +4,31 @@ import React from 'react' import { useBoolean, useClickAway } from 'ahooks' import cn from 'classnames' import { ChevronSelectorVertical } from '@/app/components/base/icons/src/vender/line/arrows' +import { Check } from '@/app/components/base/icons/src/vender/line/general' type Item = { value: string label: string } type Props = { - list: Item[] + trigger?: JSX.Element + options: Item[] value: string onChange: (value: any) => void uppercase?: boolean popupClassName?: string + readonly?: boolean + showChecked?: boolean } const TypeSelector: FC = ({ - list, + trigger, + options: list, value, onChange, uppercase, popupClassName, + readonly, + showChecked, }) => { const item = list.find(item => item.value === value) const [showOption, { setFalse: setHide, toggle: toggleShow }] = useBoolean(false) @@ -31,13 +38,24 @@ const TypeSelector: FC = ({ }, ref) return (
-
-
{item?.label}
- -
- {showOption && ( + {trigger + ? ( +
+ {trigger} +
+ ) + : ( +
+
{item?.label}
+ +
+ )} + + {(showOption && !readonly) && (
{list.map(item => (
= ({ setHide() onChange(item.value) }} - className={cn(uppercase && 'uppercase', 'flex items-center h-[30px] min-w-[44px] px-3 rounded-lg cursor-pointer text-[13px] font-medium text-gray-700 hover:bg-gray-50')} - >{item.label}
+ className={cn(uppercase && 'uppercase', 'flex items-center h-[30px] justify-between min-w-[44px] px-3 rounded-lg cursor-pointer text-[13px] font-medium text-gray-700 hover:bg-gray-50')} + > +
{item.label}
+ {showChecked && item.value === value && } +
)) }
diff --git a/web/app/components/workflow/nodes/code/panel.tsx b/web/app/components/workflow/nodes/code/panel.tsx index 735642150e..10c807849d 100644 --- a/web/app/components/workflow/nodes/code/panel.tsx +++ b/web/app/components/workflow/nodes/code/panel.tsx @@ -9,7 +9,7 @@ import AddButton from '@/app/components/base/button/add-button' import Field from '@/app/components/workflow/nodes/_base/components/field' import Split from '@/app/components/workflow/nodes/_base/components/split' import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' -import TypeSelector from '@/app/components/workflow/nodes/_base/components/editor/type-selector' +import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector' const i18nPrefix = 'workflow.nodes.code' const codeLanguages = [ @@ -54,7 +54,7 @@ const Panel: FC = () => { diff --git a/web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx b/web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx new file mode 100644 index 0000000000..450d4cd447 --- /dev/null +++ b/web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx @@ -0,0 +1,60 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import produce from 'immer' +import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker' +import type { ValueSelector } from '@/app/components/workflow/types' +import { Trash03 } from '@/app/components/base/icons/src/vender/line/general' + +type Props = { + readonly: boolean + list: ValueSelector[] + onChange: (list: ValueSelector[]) => void +} + +const VarList: FC = ({ + readonly, + list, + onChange, +}) => { + const handleVarReferenceChange = useCallback((index: number) => { + return (value: ValueSelector) => { + const newList = produce(list, (draft) => { + draft[index] = value + }) + 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/variable-assigner/use-var-list.ts b/web/app/components/workflow/nodes/variable-assigner/components/var-list/use-var-list.ts similarity index 64% rename from web/app/components/workflow/nodes/variable-assigner/use-var-list.ts rename to web/app/components/workflow/nodes/variable-assigner/components/var-list/use-var-list.ts index 6d9c72ef31..84e278432f 100644 --- a/web/app/components/workflow/nodes/variable-assigner/use-var-list.ts +++ b/web/app/components/workflow/nodes/variable-assigner/components/var-list/use-var-list.ts @@ -1,7 +1,7 @@ import { useCallback } from 'react' import produce from 'immer' -import type { VariableAssignerNodeType } from './types' -import type { Variable } from '@/app/components/workflow/types' +import type { VariableAssignerNodeType } from '../../types' +import type { ValueSelector } from '@/app/components/workflow/types' type Params = { inputs: VariableAssignerNodeType @@ -11,15 +11,15 @@ function useVarList({ inputs, setInputs, }: Params) { - const handleVarListChange = useCallback((newList: Variable[]) => { - const newInputs = produce(inputs, (draft: any) => { + const handleVarListChange = useCallback((newList: ValueSelector[]) => { + const newInputs = produce(inputs, (draft) => { draft.variables = newList }) setInputs(newInputs) }, [inputs, setInputs]) const handleAddVariable = useCallback(() => { - const newInputs = produce(inputs, (draft: any) => { + const newInputs = produce(inputs, (draft) => { draft.variables.push([]) }) setInputs(newInputs) diff --git a/web/app/components/workflow/nodes/variable-assigner/panel.tsx b/web/app/components/workflow/nodes/variable-assigner/panel.tsx index 6e401a9a4e..e78b176de3 100644 --- a/web/app/components/workflow/nodes/variable-assigner/panel.tsx +++ b/web/app/components/workflow/nodes/variable-assigner/panel.tsx @@ -1,8 +1,68 @@ import type { FC } from 'react' +import { useTranslation } from 'react-i18next' +import useConfig from './use-config' +import { mockData } from './mock' +import VarList from './components/var-list' +import Field from '@/app/components/workflow/nodes/_base/components/field' +import Selector from '@/app/components/workflow/nodes/_base/components/selector' +import AddButton from '@/app/components/base/button/add-button' +import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows' +const i18nPrefix = 'workflow.nodes.variableAssigner' const Panel: FC = () => { + const { t } = useTranslation() + const readOnly = false + + const { + inputs, + handleOutputTypeChange, + handleVarListChange, + handleAddVariable, + } = useConfig(mockData) + + const typeOptions = [ + { label: t(`${i18nPrefix}.type.string`), value: 'string' }, + { label: t(`${i18nPrefix}.type.number`), value: 'number' }, + { label: t(`${i18nPrefix}.type.object`), value: 'Object' }, + { label: t(`${i18nPrefix}.type.array`), value: 'array' }, + ] + return ( -
start panel inputs
+
+
+ + +
{inputs.output_type}
+ +
+ } + popupClassName='!top-[36px] !w-[387px]' + showChecked + /> + + + } + > + + +
+ + ) } diff --git a/web/app/components/workflow/nodes/variable-assigner/use-config.ts b/web/app/components/workflow/nodes/variable-assigner/use-config.ts index 4acac1c76b..6ce4e2c945 100644 --- a/web/app/components/workflow/nodes/variable-assigner/use-config.ts +++ b/web/app/components/workflow/nodes/variable-assigner/use-config.ts @@ -1,6 +1,6 @@ import { useCallback, useState } from 'react' import produce from 'immer' -import useVarList from './use-var-list' +import useVarList from './components/var-list/use-var-list' import type { VariableAssignerNodeType } from './types' const useConfig = (initInputs: VariableAssignerNodeType) => { diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index 5511f1bc27..3cd3022877 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -90,12 +90,13 @@ const translation = { variableAssigner: { title: 'Assign variables', outputType: 'Output Type', + outputVarType: 'Output Variable Type', varNotSet: 'Variable not set', type: { string: 'String', number: 'Number', object: 'Object', - arrayObject: 'Array[Object]', + array: 'Array', }, }, }, diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index 9d48f72e08..55487189a7 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -71,8 +71,8 @@ const translation = { }, ifElse: { conditions: '条件', - and: '且', - or: '或', + and: 'and', + or: 'or', comparisonOperator: { 'contains': '包含', 'not contains': '不包含', @@ -89,12 +89,13 @@ const translation = { variableAssigner: { title: '变量赋值', outputType: '输出类型', + outputVarType: '输出变量类型', varNotSet: '未设置变量', type: { string: 'String', number: 'Number', object: 'Object', - arrayObject: 'Array[Object]', + array: 'Array', }, }, },