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 50562a2e..b87794fa 100644 --- a/web/src/app/home/bots/components/bot-form/BotForm.tsx +++ b/web/src/app/home/bots/components/bot-form/BotForm.tsx @@ -183,13 +183,6 @@ export default function BotForm({ setAdapterNameToDynamicConfigMap(adapterNameToDynamicConfigMap); } - async function onCreateMode() { } - - function onEditMode() { - console.log('onEditMode', form.getValues()); - - } - async function getBotConfig(botId: string): Promise> { const bot = (await httpClient.getBot(botId)).bot; return { @@ -503,7 +496,7 @@ export default function BotForm({ )} - diff --git a/web/src/app/home/components/home-sidebar/HomeSidebar.module.css b/web/src/app/home/components/home-sidebar/HomeSidebar.module.css index f0103254..7f08d649 100644 --- a/web/src/app/home/components/home-sidebar/HomeSidebar.module.css +++ b/web/src/app/home/components/home-sidebar/HomeSidebar.module.css @@ -24,8 +24,8 @@ .langbotIcon { width: 2.8rem; height: 2.8rem; - color: #fbfbfb; box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1); + border-radius: 8px; } .langbotTextContainer { diff --git a/web/src/app/home/layout.module.css b/web/src/app/home/layout.module.css index 312d8932..0c48d4f3 100644 --- a/web/src/app/home/layout.module.css +++ b/web/src/app/home/layout.module.css @@ -20,6 +20,7 @@ border-radius: 1.5rem 0 0 1.5rem; margin-left: 0.6rem; margin-top: 0.6rem; + box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.05); } .mainContent { 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 41ba4842..b6a4fee6 100644 --- a/web/src/app/home/models/component/llm-form/LLMForm.tsx +++ b/web/src/app/home/models/component/llm-form/LLMForm.tsx @@ -467,7 +467,7 @@ export default function LLMForm({ 删除 )} - diff --git a/web/src/app/home/plugins/plugin-installed/PluginInstalledComponent.tsx b/web/src/app/home/plugins/plugin-installed/PluginInstalledComponent.tsx index 334ab671..789d463e 100644 --- a/web/src/app/home/plugins/plugin-installed/PluginInstalledComponent.tsx +++ b/web/src/app/home/plugins/plugin-installed/PluginInstalledComponent.tsx @@ -4,6 +4,7 @@ import { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; import CreateCardComponent from '@/app/infra/basic-component/create-card-component/CreateCardComponent'; import { PluginCardVO } from '@/app/home/plugins/plugin-installed/PluginCardVO'; import PluginCardComponent from '@/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent'; +import PluginForm from '@/app/home/plugins/plugin-installed/plugin-form/PluginForm'; import styles from '@/app/home/plugins/plugins.module.css'; import { GithubIcon } from 'lucide-react'; import { httpClient } from '@/app/infra/http/HttpClient'; @@ -23,6 +24,8 @@ export interface PluginInstalledComponentRef { const PluginInstalledComponent = forwardRef((props, ref) => { const [pluginList, setPluginList] = useState([]); + const [modalOpen, setModalOpen] = useState(false); + const [selectedPlugin, setSelectedPlugin] = useState(null); useEffect(() => { initData(); @@ -57,13 +60,38 @@ const PluginInstalledComponent = forwardRef((props, useImperativeHandle(ref, () => ({ refreshPluginList: getPluginList })); + + function handlePluginClick(plugin: PluginCardVO) { + setSelectedPlugin(plugin); + setModalOpen(true); + } return (
+ + + + 插件配置 + + {selectedPlugin && ( + { + setModalOpen(false); + getPluginList(); + }} + onFormCancel={() => { + setModalOpen(false); + }} + /> + )} + + {pluginList.map((vo, index) => { return ( -
+
handlePluginClick(vo)}>
); diff --git a/web/src/app/home/plugins/plugin-installed/plugin-form/PluginForm.tsx b/web/src/app/home/plugins/plugin-installed/plugin-form/PluginForm.tsx new file mode 100644 index 00000000..2a7559b5 --- /dev/null +++ b/web/src/app/home/plugins/plugin-installed/plugin-form/PluginForm.tsx @@ -0,0 +1,88 @@ +import { useState, useEffect } from 'react'; +import { ApiRespPlugin, ApiRespPluginConfig, Plugin } from '@/app/infra/entities/api'; +import { httpClient } from '@/app/infra/http/HttpClient'; +import DynamicFormComponent from '@/app/home/components/dynamic-form/DynamicFormComponent'; +import { IDynamicFormItemSchema } from '@/app/infra/entities/form/dynamic'; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogFooter, +} from "@/components/ui/dialog"; + +export default function PluginForm({ + pluginAuthor, + pluginName, + onFormSubmit, + onFormCancel, +}: { + pluginAuthor: string; + pluginName: string; + onFormSubmit: () => void; + onFormCancel: () => void; +}) { + const [pluginInfo, setPluginInfo] = useState(); + const [pluginConfig, setPluginConfig] = useState(); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + // 获取插件信息 + httpClient.getPlugin(pluginAuthor, pluginName).then((res) => { + setPluginInfo(res.plugin); + }); + // 获取插件配置 + httpClient.getPluginConfig(pluginAuthor, pluginName).then((res) => { + setPluginConfig(res); + }); + }, [pluginAuthor, pluginName]); + + const handleSubmit = async (values: object) => { + setIsLoading(true); + try { + await httpClient.updatePluginConfig(pluginAuthor, pluginName, values); + onFormSubmit(); + } catch (error) { + console.error('更新插件配置失败:', error); + } finally { + setIsLoading(false); + } + }; + + if (!pluginInfo || !pluginConfig) { + return
加载中...
; + } + + return ( +
+
+
插件配置
+
+ {pluginInfo.description.zh_CN} +
+ +
+ +
+
+ + +
+
+
+ ); +} \ No newline at end of file diff --git a/web/src/app/home/plugins/plugin-installed/plugin-form/pluginForm.module.css b/web/src/app/home/plugins/plugin-installed/plugin-form/pluginForm.module.css new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/home/plugins/plugin-market/PluginMarketComponent.tsx b/web/src/app/home/plugins/plugin-market/PluginMarketComponent.tsx index 84643c6e..301caeda 100644 --- a/web/src/app/home/plugins/plugin-market/PluginMarketComponent.tsx +++ b/web/src/app/home/plugins/plugin-market/PluginMarketComponent.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useRef } from 'react'; import styles from '@/app/home/plugins/plugins.module.css'; import { PluginMarketCardVO } from '@/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardVO'; import PluginMarketCardComponent from '@/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardComponent'; @@ -31,6 +31,7 @@ export default function PluginMarketComponent({ const [loading, setLoading] = useState(false); const [sortByValue, setSortByValue] = useState('stars'); const [sortOrderValue, setSortOrderValue] = useState('DESC'); + const searchTimeout = useRef(null); const pageSize = 10; useEffect(() => { @@ -43,10 +44,18 @@ export default function PluginMarketComponent({ } function onInputSearchKeyword(keyword: string) { - // 这里记得加防抖,暂时没加 setSearchKeyword(keyword); - setNowPage(1); - getPluginList(1, keyword); + + // 清除之前的定时器 + if (searchTimeout.current) { + clearTimeout(searchTimeout.current); + } + + // 设置新的定时器 + searchTimeout.current = setTimeout(() => { + setNowPage(1); + getPluginList(1, keyword); + }, 500); } function getPluginList( diff --git a/web/src/app/infra/entities/api/index.ts b/web/src/app/infra/entities/api/index.ts index 85f5607a..0e16fe87 100644 --- a/web/src/app/infra/entities/api/index.ts +++ b/web/src/app/infra/entities/api/index.ts @@ -145,7 +145,7 @@ export interface Plugin { main_file: string; pkg_path: string; repository: string; - config_schema: object; + config_schema: IDynamicFormItemSchema[]; } export interface ApiRespPluginConfig {