diff --git a/web/src/app/home/bots/botConfig.module.css b/web/src/app/home/bots/botConfig.module.css index 6f2a97ff..3b13cacc 100644 --- a/web/src/app/home/bots/botConfig.module.css +++ b/web/src/app/home/bots/botConfig.module.css @@ -1,14 +1,3 @@ -.configPageContainer { - width: 100%; - height: 100%; -} - -.cardContainer { - width: 420px; - height: 220px; - border: 1px solid black; -} - .botListContainer { align-self: flex-start; justify-self: flex-start; diff --git a/web/src/app/home/bots/components/bot-form/BotForm.tsx b/web/src/app/home/bots/components/bot-form/BotForm.tsx index 156ee581..bfaafb76 100644 --- a/web/src/app/home/bots/components/bot-form/BotForm.tsx +++ b/web/src/app/home/bots/components/bot-form/BotForm.tsx @@ -1,8 +1,3 @@ -import { - BotFormEntity, - IBotFormEntity, -} from '@/app/home/bots/components/bot-form/BotFormEntity'; -import { Button, Form, Input, notification, Select, Space } from 'antd'; import { useEffect, useState } from 'react'; import { IChooseAdapterEntity } from '@/app/home/bots/components/bot-form/ChooseAdapterEntity'; import { @@ -15,20 +10,70 @@ import DynamicFormComponent from '@/app/home/components/dynamic-form/DynamicForm import { httpClient } from '@/app/infra/http/HttpClient'; import { Bot } from '@/app/infra/api/api-types'; +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" +import { z } from "zod" + +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, + DialogFooter, +} from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select" +import { Checkbox } from "@/components/ui/checkbox" + +const formSchema = z.object({ + name: z.string().min(1, { message: '机器人名称不能为空' }), + description: z.string().min(1, { message: '机器人描述不能为空' }), + adapter: z.string().min(1, { message: '适配器不能为空' }), + adapter_config: z.record(z.string(), z.any()), +}); + export default function BotForm({ initBotId, onFormSubmit, onFormCancel, + onBotDeleted, }: { initBotId?: string; - onFormSubmit: (value: IBotFormEntity) => void; - onFormCancel: (value: IBotFormEntity) => void; + onFormSubmit: (value: z.infer) => void; + onFormCancel: () => void; + onBotDeleted: () => void; }) { + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + name: '', + description: '一个机器人', + adapter: '', + adapter_config: {}, + }, + }); + + + const [showDeleteConfirmModal, setShowDeleteConfirmModal] = useState(false); + const [adapterNameToDynamicConfigMap, setAdapterNameToDynamicConfigMap] = useState(new Map()); - const [form] = Form.useForm(); + // const [form] = Form.useForm(); const [showDynamicForm, setShowDynamicForm] = useState(false); - const [dynamicForm] = Form.useForm(); + // const [dynamicForm] = Form.useForm(); const [adapterNameList, setAdapterNameList] = useState< IChooseAdapterEntity[] >([]); @@ -78,29 +123,32 @@ export default function BotForm({ }); // 拉取初始化表单信息 if (initBotId) { - getBotFieldById(initBotId).then((val) => { - form.setFieldsValue(val); + getBotConfig(initBotId).then((val) => { + // form.setFieldsValue(val); handleAdapterSelect(val.adapter); - dynamicForm.setFieldsValue(val.adapter_config); + // dynamicForm.setFieldsValue(val.adapter_config); }); } else { - form.resetFields(); + // form.resetFields(); } setAdapterNameToDynamicConfigMap(adapterNameToDynamicConfigMap); } - async function onCreateMode() {} + async function onCreateMode() { } - function onEditMode() {} + function onEditMode() { + console.log('onEditMode', form.getValues()); - async function getBotFieldById(botId: string): Promise { + } + + async function getBotConfig(botId: string): Promise> { const bot = (await httpClient.getBot(botId)).bot; - return new BotFormEntity({ + return { adapter: bot.adapter, description: bot.description, name: bot.name, adapter_config: bot.adapter_config, - }); + }; } function handleAdapterSelect(adapterName: string) { @@ -119,11 +167,11 @@ export default function BotForm({ } function handleSubmitButton() { - form.submit(); + // form.submit(); } function handleFormFinish() { - dynamicForm.submit(); + // dynamicForm.submit(); } // 只有通过外层固定表单验证才会走到这里,真正的提交逻辑在这里 @@ -132,12 +180,12 @@ export default function BotForm({ console.log('set loading', true); if (initBotId) { // 编辑提交 - console.log('submit edit', form.getFieldsValue(), value); + // console.log('submit edit', form.getFieldsValue(), value); const updateBot: Bot = { uuid: initBotId, - name: form.getFieldsValue().name, - description: form.getFieldsValue().description, - adapter: form.getFieldsValue().adapter, + name: form.getValues().name, + description: form.getValues().description, + adapter: form.getValues().adapter, adapter_config: value, }; httpClient @@ -145,55 +193,55 @@ export default function BotForm({ .then((res) => { // TODO success toast console.log('update bot success', res); - onFormSubmit(form.getFieldsValue()); - notification.success({ - message: '更新成功', - description: '机器人更新成功', - }); + onFormSubmit(form.getValues()); + // notification.success({ + // message: '更新成功', + // description: '机器人更新成功', + // }); }) .catch(() => { // TODO error toast - notification.error({ - message: '更新失败', - description: '机器人更新失败', - }); + // notification.error({ + // message: '更新失败', + // description: '机器人更新失败', + // }); }) .finally(() => { setIsLoading(false); - form.resetFields(); - dynamicForm.resetFields(); + form.reset(); + // dynamicForm.resetFields(); }); } else { // 创建提交 - console.log('submit create', form.getFieldsValue(), value); + console.log('submit create', form.getValues(), value); const newBot: Bot = { - name: form.getFieldsValue().name, - description: form.getFieldsValue().description, - adapter: form.getFieldsValue().adapter, + name: form.getValues().name, + description: form.getValues().description, + adapter: form.getValues().adapter, adapter_config: value, }; httpClient .createBot(newBot) .then((res) => { // TODO success toast - notification.success({ - message: '创建成功', - description: '机器人创建成功', - }); + // notification.success({ + // message: '创建成功', + // description: '机器人创建成功', + // }); console.log(res); - onFormSubmit(form.getFieldsValue()); + onFormSubmit(form.getValues()); }) .catch(() => { // TODO error toast - notification.error({ - message: '创建失败', - description: '机器人创建失败', - }); + // notification.error({ + // message: '创建失败', + // description: '机器人创建失败', + // }); }) .finally(() => { setIsLoading(false); - form.resetFields(); - dynamicForm.resetFields(); + form.reset(); + // dynamicForm.resetFields(); }); } setShowDynamicForm(false); @@ -203,90 +251,122 @@ export default function BotForm({ } function handleSaveButton() { - form.submit(); + form.handleSubmit(onDynamicFormSubmit)(); + } + + function deleteBot() { + if (initBotId) { + httpClient.deleteBot(initBotId).then(() => { + onBotDeleted(); + }); + } } return (
-
- - label={'机器人名称'} - name={'name'} - rules={[{ required: true, message: '该项为必填项哦~' }]} - > - - + + + + 删除确认 + + + 你确定要删除这个机器人吗? + + + + + + + - - label={'描述'} - name={'description'} - rules={[{ required: true, message: '该项为必填项哦~' }]} - > - - + + +
+ ( + + 机器人名称* + + + + + + )} + /> + ( + + 机器人描述* + + + + + + )} + /> - - label={'平台/适配器选择'} - name={'adapter'} - rules={[{ required: true, message: '该项为必填项哦~' }]} - > - { + field.onChange(value); + handleAdapterSelect(value); + }} + value={field.value} + > + + + + + + {adapterNameList.map((item) => ( + + {item.label} + + ))} + + + +
+ + + + )} + /> +
+ + + {!initBotId && ( + + )} + {initBotId && ( + + )} + + + - {showDynamicForm && ( - - )} - - {!initBotId && ( - - )} - {initBotId && ( - - )} - - ); } diff --git a/web/src/app/home/bots/components/bot-form/BotFormEntity.ts b/web/src/app/home/bots/components/bot-form/BotFormEntity.ts deleted file mode 100644 index 90ee01d6..00000000 --- a/web/src/app/home/bots/components/bot-form/BotFormEntity.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface IBotFormEntity { - name: string; - description: string; - adapter: string; - adapter_config: object; -} - -export class BotFormEntity implements IBotFormEntity { - adapter: string; - description: string; - name: string; - adapter_config: object; - - constructor(props: IBotFormEntity) { - this.adapter = props.adapter; - this.description = props.description; - this.name = props.name; - this.adapter_config = props.adapter_config; - } -} diff --git a/web/src/app/home/models/LLMConfig.module.css b/web/src/app/home/models/LLMConfig.module.css index a3678a76..1a7226ec 100644 --- a/web/src/app/home/models/LLMConfig.module.css +++ b/web/src/app/home/models/LLMConfig.module.css @@ -1,7 +1,3 @@ -.configPageContainer { - width: 100%; - height: 100%; -} .modelListContainer { align-self: flex-start; diff --git a/web/src/app/home/models/component/llm-form/LLMForm.tsx b/web/src/app/home/models/component/llm-form/LLMForm.tsx index fc06ac51..fe68a54f 100644 --- a/web/src/app/home/models/component/llm-form/LLMForm.tsx +++ b/web/src/app/home/models/component/llm-form/LLMForm.tsx @@ -1,4 +1,3 @@ -import styles from '@/app/home/models/LLMConfig.module.css'; import { SelectProps } from 'antd'; import { ICreateLLMField } from '@/app/home/models/ICreateLLMField'; import { useEffect, useState } from 'react'; @@ -258,7 +257,7 @@ export default function LLMForm({ } return ( -
+
@@ -301,6 +300,7 @@ export default function LLMForm({ )} /> + )} /> +