From 713b574c9d59904df8c19a6d964f236493ce401c Mon Sep 17 00:00:00 2001 From: balibabu Date: Thu, 12 Jun 2025 09:50:25 +0800 Subject: [PATCH] Feat: Add SwitchForm component #3221 (#8200) ### What problem does this PR solve? Feat: Add SwitchForm component #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/public/iconfont.js | 2 +- .../form/code-form/dynamic-input-variable.tsx | 7 +- .../agent/form/code-form/next-variable.tsx | 7 +- .../components/dynamic-input-variable.tsx | 7 +- .../next-dynamic-input-variable.tsx | 7 +- .../form/invoke-form/dynamic-variables.tsx | 4 +- .../pages/agent/form/switch-form/index.less | 21 - .../pages/agent/form/switch-form/index.tsx | 361 ++++++++++-------- .../agent/form/switch-form/use-values.ts | 20 + .../pages/agent/hooks/use-get-begin-query.tsx | 140 ++++--- 10 files changed, 315 insertions(+), 261 deletions(-) delete mode 100644 web/src/pages/agent/form/switch-form/index.less create mode 100644 web/src/pages/agent/form/switch-form/use-values.ts diff --git a/web/public/iconfont.js b/web/public/iconfont.js index 66daadffb..b40587442 100644 --- a/web/public/iconfont.js +++ b/web/public/iconfont.js @@ -1,5 +1,5 @@ (window._iconfont_svg_string_4909832 = - ''), + ''), ((h) => { var a = (l = (l = document.getElementsByTagName('script'))[ l.length - 1 diff --git a/web/src/pages/agent/form/code-form/dynamic-input-variable.tsx b/web/src/pages/agent/form/code-form/dynamic-input-variable.tsx index e1c961328..c207d2804 100644 --- a/web/src/pages/agent/form/code-form/dynamic-input-variable.tsx +++ b/web/src/pages/agent/form/code-form/dynamic-input-variable.tsx @@ -3,7 +3,7 @@ import { RAGFlowNodeType } from '@/interfaces/database/flow'; import { MinusCircleOutlined } from '@ant-design/icons'; import { Form, Input, Select } from 'antd'; import { useTranslation } from 'react-i18next'; -import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; +import { useBuildVariableOptions } from '../../hooks/use-get-begin-query'; import { FormCollapse } from '../components/dynamic-input-variable'; type DynamicInputVariableProps = { @@ -17,10 +17,7 @@ export const DynamicInputVariable = ({ }: DynamicInputVariableProps) => { const { t } = useTranslation(); - const valueOptions = useBuildComponentIdSelectOptions( - node?.id, - node?.parentId, - ); + const valueOptions = useBuildVariableOptions(node?.id, node?.parentId); return ( diff --git a/web/src/pages/agent/form/code-form/next-variable.tsx b/web/src/pages/agent/form/code-form/next-variable.tsx index c29fbcdcc..fe668f41b 100644 --- a/web/src/pages/agent/form/code-form/next-variable.tsx +++ b/web/src/pages/agent/form/code-form/next-variable.tsx @@ -16,7 +16,7 @@ import { X } from 'lucide-react'; import { ReactNode } from 'react'; import { useFieldArray, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; -import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; +import { useBuildVariableOptions } from '../../hooks/use-get-begin-query'; interface IProps { node?: RAGFlowNodeType; @@ -41,10 +41,7 @@ export function DynamicVariableForm({ node, name = 'arguments' }: IProps) { control: form.control, }); - const valueOptions = useBuildComponentIdSelectOptions( - node?.id, - node?.parentId, - ); + const valueOptions = useBuildVariableOptions(node?.id, node?.parentId); return (
diff --git a/web/src/pages/agent/form/components/dynamic-input-variable.tsx b/web/src/pages/agent/form/components/dynamic-input-variable.tsx index 82082e6b8..a5781fd16 100644 --- a/web/src/pages/agent/form/components/dynamic-input-variable.tsx +++ b/web/src/pages/agent/form/components/dynamic-input-variable.tsx @@ -3,7 +3,7 @@ import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; import { Button, Collapse, Flex, Form, Input, Select } from 'antd'; import { PropsWithChildren, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; +import { useBuildVariableOptions } from '../../hooks/use-get-begin-query'; import styles from './index.less'; @@ -21,10 +21,7 @@ const getVariableName = (type: string) => const DynamicVariableForm = ({ node }: IProps) => { const { t } = useTranslation(); - const valueOptions = useBuildComponentIdSelectOptions( - node?.id, - node?.parentId, - ); + const valueOptions = useBuildVariableOptions(node?.id, node?.parentId); const form = Form.useFormInstance(); const options = [ diff --git a/web/src/pages/agent/form/components/next-dynamic-input-variable.tsx b/web/src/pages/agent/form/components/next-dynamic-input-variable.tsx index d22bea406..341b49f37 100644 --- a/web/src/pages/agent/form/components/next-dynamic-input-variable.tsx +++ b/web/src/pages/agent/form/components/next-dynamic-input-variable.tsx @@ -20,7 +20,7 @@ import { RAGFlowNodeType } from '@/interfaces/database/flow'; import { Plus, Trash2 } from 'lucide-react'; import { useFieldArray, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; -import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; +import { useBuildVariableOptions } from '../../hooks/use-get-begin-query'; interface IProps { node?: RAGFlowNodeType; @@ -42,10 +42,7 @@ export function DynamicVariableForm({ node }: IProps) { control: form.control, }); - const valueOptions = useBuildComponentIdSelectOptions( - node?.id, - node?.parentId, - ); + const valueOptions = useBuildVariableOptions(node?.id, node?.parentId); const options = [ { value: VariableType.Reference, label: t('flow.reference') }, diff --git a/web/src/pages/agent/form/invoke-form/dynamic-variables.tsx b/web/src/pages/agent/form/invoke-form/dynamic-variables.tsx index 9a67c1f78..f98c04d63 100644 --- a/web/src/pages/agent/form/invoke-form/dynamic-variables.tsx +++ b/web/src/pages/agent/form/invoke-form/dynamic-variables.tsx @@ -3,7 +3,7 @@ import { useTranslate } from '@/hooks/common-hooks'; import { DeleteOutlined } from '@ant-design/icons'; import { Button, Collapse, Flex, Input, Select, Table, TableProps } from 'antd'; import { trim } from 'lodash'; -import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; +import { useBuildVariableOptions } from '../../hooks/use-get-begin-query'; import { IInvokeVariable } from '../../interface'; import { useHandleOperateParameters } from './hooks'; @@ -25,7 +25,7 @@ const DynamicVariablesForm = ({ node }: IProps) => { const nodeId = node?.id; const { t } = useTranslate('flow'); - const options = useBuildComponentIdSelectOptions(nodeId, node?.parentId); + const options = useBuildVariableOptions(nodeId, node?.parentId); const { dataSource, handleAdd, diff --git a/web/src/pages/agent/form/switch-form/index.less b/web/src/pages/agent/form/switch-form/index.less deleted file mode 100644 index c5e2c7fe8..000000000 --- a/web/src/pages/agent/form/switch-form/index.less +++ /dev/null @@ -1,21 +0,0 @@ -@lightBackgroundColor: rgba(150, 150, 150, 0.07); -@darkBackgroundColor: rgba(150, 150, 150, 0.12); - -.caseCard { - background-color: @lightBackgroundColor; -} - -.conditionCard { - background-color: @darkBackgroundColor; -} - -.elseCase { - background-color: @lightBackgroundColor; - padding: 12px; - border-radius: 8px; -} - -.addButton { - color: rgb(22, 119, 255); - font-weight: 600; -} diff --git a/web/src/pages/agent/form/switch-form/index.tsx b/web/src/pages/agent/form/switch-form/index.tsx index 222a2baa3..35306375b 100644 --- a/web/src/pages/agent/form/switch-form/index.tsx +++ b/web/src/pages/agent/form/switch-form/index.tsx @@ -1,31 +1,179 @@ -import { CloseOutlined } from '@ant-design/icons'; -import { Button, Card, Divider, Form, Input, Select } from 'antd'; +import { FormContainer } from '@/components/form-container'; +import { BlockButton, Button } from '@/components/ui/button'; +import { Card, CardContent } from '@/components/ui/card'; +import { + Form, + FormControl, + FormField, + FormItem, + FormMessage, +} from '@/components/ui/form'; +import { RAGFlowSelect } from '@/components/ui/select'; +import { Textarea } from '@/components/ui/textarea'; +import { ISwitchForm } from '@/interfaces/database/flow'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { X } from 'lucide-react'; import { useMemo } from 'react'; +import { useFieldArray, useForm, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; +import { z } from 'zod'; import { Operator, - SwitchElseTo, SwitchLogicOperatorOptions, SwitchOperatorOptions, } from '../../constant'; import { useBuildFormSelectOptions } from '../../form-hooks'; -import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; +import { + useBuildComponentIdAndBeginOptions, + useBuildVariableOptions, +} from '../../hooks/use-get-begin-query'; import { IOperatorForm } from '../../interface'; -import { getOtherFieldValues } from '../../utils'; +import { useValues } from './use-values'; -import { ISwitchForm } from '@/interfaces/database/flow'; -import styles from './index.less'; +const ConditionKey = 'conditions'; +const ItemKey = 'items'; -const SwitchForm = ({ onValuesChange, node, form }: IOperatorForm) => { +type ConditionCardsProps = { + name: string; +} & IOperatorForm; + +function ConditionCards({ name: parentName, node }: ConditionCardsProps) { + const form = useFormContext(); const { t } = useTranslation(); + + const componentIdOptions = useBuildComponentIdAndBeginOptions( + node?.id, + node?.parentId, + ); + + const switchOperatorOptions = useMemo(() => { + return SwitchOperatorOptions.map((x) => ({ + value: x.value, + label: t(`flow.switchOperatorOptions.${x.label}`), + })); + }, [t]); + + const name = `${parentName}.${ItemKey}`; + + const { fields, remove, append } = useFieldArray({ + name: name, + control: form.control, + }); + + return ( +
+ {fields.map((field, index) => { + return ( +
+ +
+ ( + + + + + + + )} + /> + ( + + + + + + + )} + /> +
+ + ( + + +