'use client'; import { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; import { MCPCardVO } from '@/app/home/plugins/mcp/MCPCardVO'; import MCPCardComponent from '@/app/home/plugins/mcp/mcp-card/MCPCardComponent'; import MCPForm from '@/app/home/plugins/mcp/mcp-form/MCPForm'; import styles from '@/app/home/plugins/plugins.module.css'; import { httpClient } from '@/app/infra/http/HttpClient'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { useTranslation } from 'react-i18next'; import { toast } from 'sonner'; export interface MCPComponentRef { refreshServerList: () => void; createServer: () => void; } // eslint-disable-next-line react/display-name const MCPComponent = forwardRef((props, ref) => { const { t } = useTranslation(); const [serverList, setServerList] = useState([]); const [modalOpen, setModalOpen] = useState(false); const [selectedServer, setSelectedServer] = useState(null); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [serverToDelete, setServerToDelete] = useState(null); const [deleting, setDeleting] = useState(false); useEffect(() => { initData(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); function initData() { getServerList(); } function getServerList() { httpClient .getMCPServers() .then((value) => { setServerList(value.servers.map((server) => new MCPCardVO(server))); }) .catch((error) => { toast.error(t('mcp.getServerListError') + error.message); }); } useImperativeHandle(ref, () => ({ refreshServerList: getServerList, createServer: () => { setSelectedServer(null); setModalOpen(true); }, })); function handleServerClick(server: MCPCardVO) { setSelectedServer(server); setModalOpen(true); } function handleDeleteClick(server: MCPCardVO, e: React.MouseEvent) { e.stopPropagation(); setServerToDelete(server); setDeleteDialogOpen(true); } async function confirmDelete() { if (!serverToDelete) return; setDeleting(true); try { const response = await httpClient.deleteMCPServer(serverToDelete.name); const taskId = response.task_id; // 监控任务状态 const interval = setInterval(() => { httpClient.getAsyncTask(taskId).then((taskResp) => { if (taskResp.runtime.done) { clearInterval(interval); setDeleting(false); setDeleteDialogOpen(false); if (taskResp.runtime.exception) { toast.error(t('mcp.deleteError') + taskResp.runtime.exception); } else { toast.success(t('mcp.deleteSuccess')); getServerList(); } } }); }, 1000); } catch (error: unknown) { setDeleting(false); const errorMessage = error instanceof Error ? error.message : String(error); toast.error(t('mcp.deleteError') + errorMessage); } } return ( <> {serverList.length === 0 ? (
{t('mcp.noServerInstalled')}
) : (
{serverList.map((vo, index) => { return (
handleServerClick(vo)} onRefresh={getServerList} /> {/* 删除按钮 */}
); })}
)} {/* 编辑配置对话框 */} {selectedServer ? t('mcp.editServer') : t('mcp.createServer')}
{ setModalOpen(false); getServerList(); }} onFormCancel={() => { setModalOpen(false); }} />
{/* 删除确认对话框 */} {t('mcp.deleteServer')} {t('mcp.confirmDeleteServer', { name: serverToDelete?.name })} {t('common.cancel')} {deleting ? t('plugins.deleting') : t('common.delete')} ); }); export default MCPComponent;