From 166eebabff6329f63326445f4c629efee7a4245c Mon Sep 17 00:00:00 2001
From: WangCham <651122857@qq.com>
Date: Tue, 28 Oct 2025 13:11:09 +0800
Subject: [PATCH] fix: delete mcp market
---
.../MCPServerComponent.tsx} | 2 +-
.../MCPServerCardComponent.tsx} | 2 +-
.../mcp-market-card/MCPServerCardVO.ts} | 0
web/src/app/home/plugins/page.tsx | 119 +++++++++---------
4 files changed, 64 insertions(+), 59 deletions(-)
rename web/src/app/home/plugins/{mcp-market/MCPMarketComponent.tsx => mcp-server/MCPServerComponent.tsx} (99%)
rename web/src/app/home/plugins/{mcp-market/mcp-market-card/MCPMarketCardComponent.tsx => mcp-server/mcp-market-card/MCPServerCardComponent.tsx} (98%)
rename web/src/app/home/plugins/{mcp-market/mcp-market-card/MCPMarketCardVO.ts => mcp-server/mcp-market-card/MCPServerCardVO.ts} (100%)
diff --git a/web/src/app/home/plugins/mcp-market/MCPMarketComponent.tsx b/web/src/app/home/plugins/mcp-server/MCPServerComponent.tsx
similarity index 99%
rename from web/src/app/home/plugins/mcp-market/MCPMarketComponent.tsx
rename to web/src/app/home/plugins/mcp-server/MCPServerComponent.tsx
index 28f6ff86..83fc0851 100644
--- a/web/src/app/home/plugins/mcp-market/MCPMarketComponent.tsx
+++ b/web/src/app/home/plugins/mcp-server/MCPServerComponent.tsx
@@ -168,7 +168,7 @@ export default function MCPMarketComponent({
) : installedServers.length === 0 ? (
- {t('mcp.noInstalledServers')}
+ {t('mcp.noServerInstalled')}
) : (
installedServers.map((server, index) => (
diff --git a/web/src/app/home/plugins/mcp-market/mcp-market-card/MCPMarketCardComponent.tsx b/web/src/app/home/plugins/mcp-server/mcp-market-card/MCPServerCardComponent.tsx
similarity index 98%
rename from web/src/app/home/plugins/mcp-market/mcp-market-card/MCPMarketCardComponent.tsx
rename to web/src/app/home/plugins/mcp-server/mcp-market-card/MCPServerCardComponent.tsx
index 330fe228..2190147f 100644
--- a/web/src/app/home/plugins/mcp-market/mcp-market-card/MCPMarketCardComponent.tsx
+++ b/web/src/app/home/plugins/mcp-server/mcp-market-card/MCPServerCardComponent.tsx
@@ -1,4 +1,4 @@
-import { MCPMarketCardVO } from '@/app/home/plugins/mcp-market/mcp-market-card/MCPMarketCardVO';
+import { MCPMarketCardVO } from '@/app/home/plugins/mcp-server/mcp-market-card/MCPServerCardVO';
import { Button } from '@/components/ui/button';
import { useTranslation } from 'react-i18next';
diff --git a/web/src/app/home/plugins/mcp-market/mcp-market-card/MCPMarketCardVO.ts b/web/src/app/home/plugins/mcp-server/mcp-market-card/MCPServerCardVO.ts
similarity index 100%
rename from web/src/app/home/plugins/mcp-market/mcp-market-card/MCPMarketCardVO.ts
rename to web/src/app/home/plugins/mcp-server/mcp-market-card/MCPServerCardVO.ts
diff --git a/web/src/app/home/plugins/page.tsx b/web/src/app/home/plugins/page.tsx
index 6d02627c..8793daa3 100644
--- a/web/src/app/home/plugins/page.tsx
+++ b/web/src/app/home/plugins/page.tsx
@@ -7,7 +7,7 @@ import MarketPage from '@/app/home/plugins/plugin-market/PluginMarketComponent';
import MCPComponent, {
MCPComponentRef,
} from '@/app/home/plugins/mcp/MCPComponent';
-import MCPMarketComponent from '@/app/home/plugins/mcp-market/MCPMarketComponent';
+import MCPServerComponent from '@/app/home/plugins/mcp-server/MCPServerComponent';
import styles from './plugins.module.css';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
@@ -48,7 +48,7 @@ import {
SelectItem,
} from "@/components/ui/select"
-import { useForm } from 'react-hook-form';
+import { Resolver, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { DialogDescription } from '@radix-ui/react-dialog';
@@ -121,26 +121,48 @@ export default function PluginConfigPage() {
form.setValue('extra_args', newArgs);
};
const getFormSchema = (t: (key: string) => string) =>
- z.object({
- name: z.string().min(1, { message: t('mcp.nameRequired') }),
- timeout: z.number().min(30, { message: t('mcp.timeoutMin30') }),
- ssereadtimeout: z
- .number()
- .min(300, { message: t('mcp.sseTimeoutMin300') }),
- url: z.string().min(1, { message: t('mcp.requestURLRequired') }),
- extra_args: z.array(getExtraArgSchema(t)).optional(),
- });
- const formSchema = getFormSchema(t);
- const form = useForm>({
- resolver: zodResolver(formSchema),
- defaultValues: {
- name: '',
- url: '',
- timeout: 30,
- ssereadtimeout: 300,
- extra_args: [],
- },
+ z.object({
+ name: z.string({ required_error: t('mcp.nameRequired') }),
+ timeout: z
+ .number({ invalid_type_error: t('mcp.timeoutMustBeNumber') })
+ .nonnegative({ message: t('mcp.timeoutNonNegative') })
+ .default(30),
+ ssereadtimeout: z
+ .number({ invalid_type_error: t('mcp.sseTimeoutMustBeNumber') })
+ .nonnegative({ message: t('mcp.sseTimeoutNonNegative') })
+ .default(300),
+ url: z.string({ required_error: t('models.requestURLRequired') }),
+ extra_args: z
+ .array(
+ z.object({
+ key: z.string(),
+ type: z.enum(['string', 'number', 'boolean']),
+ value: z.string(),
+ })
+ )
+ .optional(),
});
+
+const formSchema = getFormSchema(t);
+
+
+type FormValues = z.infer & {
+ timeout: number;
+ ssereadtimeout: number;
+};
+
+const form = useForm({
+ resolver: zodResolver(formSchema) as unknown as Resolver,
+ defaultValues: {
+ name: '',
+ url: '',
+ timeout: 30,
+ ssereadtimeout: 300,
+ extra_args: [],
+ },
+});
+
+
const [extraArgs, setExtraArgs] = useState<
{ key: string; type: 'string' | 'number' | 'boolean'; value: string }[]
>([]);
@@ -274,24 +296,12 @@ export default function PluginConfigPage() {
});
if (!mcpSSEModalOpen && !modalOpen && !showDeleteConfirmModal) {
- console.log(
- '[Dialog Debug] All dialogs closed, cleaning up body styles...',
- );
- console.log(
- '[Dialog Debug] Before cleanup - body.style.pointerEvents:',
- document.body.style.pointerEvents,
- );
- console.log(
- '[Dialog Debug] Before cleanup - body.style.overflow:',
- document.body.style.overflow,
- );
-
const cleanup = () => {
- // 强制移除 body 上可能残留的样式
+
document.body.style.removeProperty('pointer-events');
document.body.style.removeProperty('overflow');
- // 如果 removeProperty 不起作用,强制设置为空字符串
+
if (document.body.style.pointerEvents === 'none') {
document.body.style.pointerEvents = '';
}
@@ -334,7 +344,7 @@ export default function PluginConfigPage() {
}
}, [mcpSSEModalOpen, modalOpen, showDeleteConfirmModal]);
- // 额外的全局清理:定期检查并清理
+
useEffect(() => {
const interval = setInterval(() => {
if (!mcpSSEModalOpen && !modalOpen && !showDeleteConfirmModal) {
@@ -454,16 +464,16 @@ export default function PluginConfigPage() {
async function loadServerForEdit(serverName: string) {
try {
const resp = await httpClient.getMCPServer(serverName);
- const server = resp.server ?? resp; // 有的接口包了一层,有的直接返回对象
+ const server = resp.server ?? resp;
console.log('Loaded server for edit:', server);
- // 填充表单数据
+
form.setValue('name', server.name);
form.setValue('url', server.extra_args?.url || '');
form.setValue('timeout', server.extra_args?.timeout || 30);
form.setValue('ssereadtimeout', server.extra_args?.ssereadtimeout || 300);
- // 填充 headers
+
if (server.extra_args?.headers) {
const headers = Object.entries(server.extra_args.headers).map(
([key, value]) => ({
@@ -476,23 +486,23 @@ export default function PluginConfigPage() {
form.setValue('extra_args', headers);
}
- // 重置测试状态
+
setMcpTestStatus('testing');
setMcpToolNames([]);
setMcpTestError('');
- // 打开对话框
+
setEditingServerName(serverName);
setIsEditMode(true);
setMcpSSEModalOpen(true);
- // 在这里测试工具连接状态
+
try {
const res = await httpClient.testMCPServer(server.name);
if (res.task_id) {
const taskId = res.task_id;
- // 监听任务完成
+
const interval = setInterval(() => {
httpClient.getAsyncTask(taskId).then((taskResp) => {
console.log('Task response:', taskResp);
@@ -505,13 +515,13 @@ export default function PluginConfigPage() {
console.log('Exception:', taskResp.runtime.exception);
if (taskResp.runtime.exception) {
- // 测试失败
+
console.log('Test failed with exception');
setMcpTestStatus('failed');
setMcpToolNames([]);
setMcpTestError(taskResp.runtime.exception || '未知错误');
} else if (taskResp.runtime.result) {
- // 测试成功 - 后端可能返回字符串或对象
+
try {
let result: {
status?: string;
@@ -520,7 +530,7 @@ export default function PluginConfigPage() {
error?: string;
};
- // 如果result是字符串,需要先解析
+
const rawResult: any = taskResp.runtime.result;
if (typeof rawResult === 'string') {
console.log('Result is string, parsing...');
@@ -614,25 +624,21 @@ export default function PluginConfigPage() {
};
if (isEditMode && editingServerName) {
- // 编辑模式:更新服务器
+
await httpClient.updateMCPServer(editingServerName, serverConfig);
toast.success(t('mcp.updateSuccess'));
} else {
- // 创建模式:新建服务器
await httpClient.createMCPServer(serverConfig);
toast.success(t('mcp.createSuccess'));
}
- // 只有在异步操作成功后才关闭对话框
setMcpSSEModalOpen(false);
- // 重置表单和状态
form.reset();
setExtraArgs([]);
setEditingServerName(null);
setIsEditMode(false);
- // 刷新服务器列表
setRefreshKey((prev) => prev + 1);
} catch (error) {
console.error('Failed to save MCP server:', error);
@@ -706,7 +712,7 @@ export default function PluginConfigPage() {
if (file) {
uploadPluginFile(file);
}
- // 清空input值,以便可以重复选择同一个文件
+
event.target.value = '';
},
[uploadPluginFile],
@@ -748,7 +754,7 @@ export default function PluginConfigPage() {
[uploadPluginFile, isPluginSystemReady, t],
);
- // 插件系统未启用的状态显示
+
const renderPluginDisabledState = () => (
@@ -761,7 +767,7 @@ export default function PluginConfigPage() {
);
- // 插件系统连接异常的状态显示
+
const renderPluginConnectionErrorState = () => (