From 9e80f39caa90fe6cd1682d4fc7445f01d8edcf69 Mon Sep 17 00:00:00 2001 From: balibabu Date: Fri, 23 May 2025 09:49:14 +0800 Subject: [PATCH] Feat: Synchronize BeginForm's query data to the canvas #3221 (#7798) ### What problem does this PR solve? Feat: Synchronize BeginForm's query data to the canvas #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- .../form/begin-form/begin-dynamic-options.tsx | 121 ++++++++--------- web/src/pages/agent/form/begin-form/index.tsx | 30 ++--- .../begin-form/next-begin-dynamic-options.tsx | 62 --------- .../agent/form/begin-form/paramater-modal.tsx | 124 ------------------ ...amater-dialog.tsx => parameter-dialog.tsx} | 20 ++- .../{hooks.ts => use-edit-query.ts} | 50 ++++++- 6 files changed, 130 insertions(+), 277 deletions(-) delete mode 100644 web/src/pages/agent/form/begin-form/next-begin-dynamic-options.tsx delete mode 100644 web/src/pages/agent/form/begin-form/paramater-modal.tsx rename web/src/pages/agent/form/begin-form/{paramater-dialog.tsx => parameter-dialog.tsx} (90%) rename web/src/pages/agent/form/begin-form/{hooks.ts => use-edit-query.ts} (50%) diff --git a/web/src/pages/agent/form/begin-form/begin-dynamic-options.tsx b/web/src/pages/agent/form/begin-form/begin-dynamic-options.tsx index bcc9c5788..3531f8927 100644 --- a/web/src/pages/agent/form/begin-form/begin-dynamic-options.tsx +++ b/web/src/pages/agent/form/begin-form/begin-dynamic-options.tsx @@ -1,68 +1,61 @@ -import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; -import { Button, Form, Input } from 'antd'; +'use client'; + +import { BlockButton, Button } from '@/components/ui/button'; +import { + FormControl, + FormField, + FormItem, + FormMessage, +} from '@/components/ui/form'; +import { Input } from '@/components/ui/input'; +import { X } from 'lucide-react'; +import { useFieldArray, useFormContext } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; + +export function BeginDynamicOptions() { + const { t } = useTranslation(); + const form = useFormContext(); + const name = 'options'; + + const { fields, remove, append } = useFieldArray({ + name: name, + control: form.control, + }); -const BeginDynamicOptions = () => { return ( - { - if (!names || names.length < 1) { - return Promise.reject(new Error('At least 1 option')); - } - }, - }, - ]} - > - {(fields, { add, remove }, { errors }) => ( - <> - {fields.map((field, index) => ( - - - - - {fields.length > 1 ? ( - remove(field.name)} - /> - ) : null} - - ))} - - - - - - )} - + + ); + })} + append({ value: '' })} + variant={'outline'} + type="button" + > + {t('flow.addVariable')} + + ); -}; - -export default BeginDynamicOptions; +} diff --git a/web/src/pages/agent/form/begin-form/index.tsx b/web/src/pages/agent/form/begin-form/index.tsx index 30a6ef0a6..49c12601c 100644 --- a/web/src/pages/agent/form/begin-form/index.tsx +++ b/web/src/pages/agent/form/begin-form/index.tsx @@ -15,16 +15,16 @@ import { useCallback } from 'react'; import { useWatch } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { AgentDialogueMode } from '../../constant'; -import { BeginQuery, INextOperatorForm } from '../../interface'; -import { useEditQueryRecord } from './hooks'; -import { ParameterDialog } from './paramater-dialog'; +import { INextOperatorForm } from '../../interface'; +import { ParameterDialog } from './parameter-dialog'; import QueryTable from './query-table'; +import { useEditQueryRecord } from './use-edit-query'; const ModeOptions = buildSelectOptions([ (AgentDialogueMode.Conversational, AgentDialogueMode.Task), ]); -const BeginForm = ({ form }: INextOperatorForm) => { +const BeginForm = ({ form, node }: INextOperatorForm) => { const { t } = useTranslation(); const query = useWatch({ control: form.control, name: 'query' }); @@ -40,22 +40,17 @@ const BeginForm = ({ form }: INextOperatorForm) => { hideModal, showModal, otherThanCurrentQuery, + handleDeleteRecord, } = useEditQueryRecord({ form, + node, }); - const handleDeleteRecord = useCallback( - (idx: number) => { - const query = form?.getValues('query') || []; - const nextQuery = query.filter( - (item: BeginQuery, index: number) => index !== idx, - ); - // onValuesChange?.( - // { query: nextQuery }, - // { query: nextQuery, prologue: form?.getFieldValue('prologue') }, - // ); + const handleParameterDialogSubmit = useCallback( + (values: any) => { + ok(values); }, - [form], + [ok], ); return ( @@ -118,11 +113,11 @@ const BeginForm = ({ form }: INextOperatorForm) => { /> )} {/* Create a hidden field to make Form instance record this */} - {/*
} - /> */} + /> { initialValue={currentRecord} onOk={ok} otherThanCurrentQuery={otherThanCurrentQuery} + submit={handleParameterDialogSubmit} > )} diff --git a/web/src/pages/agent/form/begin-form/next-begin-dynamic-options.tsx b/web/src/pages/agent/form/begin-form/next-begin-dynamic-options.tsx deleted file mode 100644 index 1d0db395d..000000000 --- a/web/src/pages/agent/form/begin-form/next-begin-dynamic-options.tsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client'; - -import { Button } from '@/components/ui/button'; -import { - FormControl, - FormField, - FormItem, - FormMessage, -} from '@/components/ui/form'; -import { Input } from '@/components/ui/input'; -import { Plus, X } from 'lucide-react'; -import { useFieldArray, useFormContext } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; - -export function BeginDynamicOptions() { - const { t } = useTranslation(); - const form = useFormContext(); - const name = 'options'; - - const { fields, remove, append } = useFieldArray({ - name: name, - control: form.control, - }); - - return ( -
- {fields.map((field, index) => { - const typeField = `${name}.${index}`; - return ( -
- ( - - - - - - - )} - /> - -
- ); - })} - -
- ); -} diff --git a/web/src/pages/agent/form/begin-form/paramater-modal.tsx b/web/src/pages/agent/form/begin-form/paramater-modal.tsx deleted file mode 100644 index 7d689601b..000000000 --- a/web/src/pages/agent/form/begin-form/paramater-modal.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { useResetFormOnCloseModal } from '@/hooks/logic-hooks'; -import { IModalProps } from '@/interfaces/common'; -import { Form, Input, Modal, Select, Switch } from 'antd'; -import { DefaultOptionType } from 'antd/es/select'; -import { useEffect, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { BeginQueryType, BeginQueryTypeIconMap } from '../../constant'; -import { BeginQuery } from '../../interface'; -import BeginDynamicOptions from './begin-dynamic-options'; - -export const ModalForm = ({ - visible, - initialValue, - hideModal, - otherThanCurrentQuery, -}: IModalProps & { - initialValue: BeginQuery; - otherThanCurrentQuery: BeginQuery[]; -}) => { - const { t } = useTranslation(); - const [form] = Form.useForm(); - const options = useMemo(() => { - return Object.values(BeginQueryType).reduce( - (pre, cur) => { - const Icon = BeginQueryTypeIconMap[cur]; - - return [ - ...pre, - { - label: ( -
- - {cur} -
- ), - value: cur, - }, - ]; - }, - [], - ); - }, []); - - useResetFormOnCloseModal({ - form, - visible: visible, - }); - - useEffect(() => { - form.setFieldsValue(initialValue); - }, [form, initialValue]); - - const onOk = () => { - form.submit(); - }; - - return ( - -
- - - - - - - - - - - prevValues.type !== curValues.type - } - > - {({ getFieldValue }) => { - const type: BeginQueryType = getFieldValue('type'); - return ( - type === BeginQueryType.Options && ( - - ) - ); - }} - -
-
- ); -}; diff --git a/web/src/pages/agent/form/begin-form/paramater-dialog.tsx b/web/src/pages/agent/form/begin-form/parameter-dialog.tsx similarity index 90% rename from web/src/pages/agent/form/begin-form/paramater-dialog.tsx rename to web/src/pages/agent/form/begin-form/parameter-dialog.tsx index 13e31bd1a..c1aec022b 100644 --- a/web/src/pages/agent/form/begin-form/paramater-dialog.tsx +++ b/web/src/pages/agent/form/begin-form/parameter-dialog.tsx @@ -25,11 +25,12 @@ import { useTranslation } from 'react-i18next'; import { z } from 'zod'; import { BeginQueryType, BeginQueryTypeIconMap } from '../../constant'; import { BeginQuery } from '../../interface'; -import { BeginDynamicOptions } from './next-begin-dynamic-options'; +import { BeginDynamicOptions } from './begin-dynamic-options'; type ModalFormProps = { initialValue: BeginQuery; otherThanCurrentQuery: BeginQuery[]; + submit(values: any): void; }; const FormId = 'BeginParameterForm'; @@ -37,6 +38,7 @@ const FormId = 'BeginParameterForm'; function ParameterForm({ initialValue, otherThanCurrentQuery, + submit, }: ModalFormProps) { const FormSchema = z.object({ type: z.string(), @@ -51,7 +53,9 @@ function ParameterForm({ ), optional: z.boolean(), name: z.string().trim().min(1), - options: z.array(z.string().or(z.boolean()).or(z.number())).optional(), + options: z + .array(z.object({ value: z.string().or(z.boolean()).or(z.number()) })) + .optional(), }); const form = useForm>({ @@ -94,11 +98,17 @@ function ParameterForm({ }); useEffect(() => { - form.reset(initialValue); + form.reset({ + ...initialValue, + options: initialValue.options?.map((x) => ({ value: x })), + }); }, [form, initialValue]); function onSubmit(data: z.infer) { - console.log('🚀 ~ onSubmit ~ data:', data); + const values = { ...data, options: data.options?.map((x) => x.value) }; + console.log('🚀 ~ onSubmit ~ values:', values); + + submit(values); } return ( @@ -176,6 +186,7 @@ export function ParameterDialog({ initialValue, hideModal, otherThanCurrentQuery, + submit, }: ModalFormProps & IModalProps) { const { t } = useTranslation(); @@ -188,6 +199,7 @@ export function ParameterDialog({