feat: add server toggle functionality

This commit is contained in:
samanhappy@qq.com
2025-04-14 22:25:07 +08:00
parent 40d8792294
commit 2e1f73ef64
9 changed files with 264 additions and 50 deletions

View File

@@ -275,6 +275,34 @@ const Dashboard = () => {
}
}
const handleServerToggle = async (server: Server, enabled: boolean) => {
try {
const token = localStorage.getItem('mcphub_token');
const response = await fetch(`/api/servers/${server.name}/toggle`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-token': token || ''
},
body: JSON.stringify({ enabled }),
});
const result = await response.json();
if (!response.ok) {
console.error('Failed to toggle server:', result);
setError(t('server.toggleError', { serverName: server.name }));
return;
}
// Update the UI immediately to reflect the change
setRefreshKey(prevKey => prevKey + 1);
} catch (err) {
console.error('Error toggling server:', err);
setError(err instanceof Error ? err.message : String(err));
}
};
const handleLogout = () => {
logout()
navigate('/login')
@@ -333,6 +361,7 @@ const Dashboard = () => {
server={server}
onRemove={handleServerRemove}
onEdit={handleServerEdit}
onToggle={handleServerToggle}
/>
))}
</div>

View File

@@ -10,12 +10,14 @@ interface ServerCardProps {
server: Server
onRemove: (serverName: string) => void
onEdit: (server: Server) => void
onToggle?: (server: Server, enabled: boolean) => void
}
const ServerCard = ({ server, onRemove, onEdit }: ServerCardProps) => {
const ServerCard = ({ server, onRemove, onEdit, onToggle }: ServerCardProps) => {
const { t } = useTranslation()
const [isExpanded, setIsExpanded] = useState(false)
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
const [isToggling, setIsToggling] = useState(false)
const handleRemove = (e: React.MouseEvent) => {
e.stopPropagation()
@@ -27,6 +29,19 @@ const ServerCard = ({ server, onRemove, onEdit }: ServerCardProps) => {
onEdit(server)
}
const handleToggle = async (e: React.MouseEvent) => {
e.stopPropagation()
if (isToggling || !onToggle) return
setIsToggling(true)
try {
// Toggle the server's enabled status
await onToggle(server, !(server.enabled !== false))
} finally {
setIsToggling(false)
}
}
const handleConfirmDelete = () => {
onRemove(server.name)
setShowDeleteDialog(false)
@@ -55,6 +70,26 @@ const ServerCard = ({ server, onRemove, onEdit }: ServerCardProps) => {
>
{t('server.delete')}
</button>
<div className="flex items-center">
<button
onClick={handleToggle}
className={`px-3 py-1 text-sm rounded transition-colors ${
isToggling
? 'bg-gray-200 text-gray-500'
: server.enabled !== false
? 'bg-green-100 text-green-800 hover:bg-green-200'
: 'bg-gray-100 text-gray-800 hover:bg-gray-200'
}`}
disabled={isToggling}
>
{isToggling
? t('common.processing')
: server.enabled !== false
? t('server.disable')
: t('server.enable')
}
</button>
</div>
<button className="text-gray-400 hover:text-gray-600">
{isExpanded ? <ChevronDown size={18} /> : <ChevronRight size={18} />}
</button>

View File

@@ -3,7 +3,7 @@
"title": "MCP Hub Dashboard",
"error": "Error",
"closeButton": "Close",
"noServers": "No MCP servers available",
"noServers": "No servers found. Add a new server to get started.",
"loading": "Loading...",
"logout": "Logout",
"profile": "Profile",
@@ -24,7 +24,14 @@
"passwordsNotMatch": "New password and confirmation do not match",
"changePasswordSuccess": "Password changed successfully",
"changePasswordError": "Failed to change password",
"changePassword": "Change Password"
"changePassword": "Change Password",
"confirmNewPassword": "Confirm New Password",
"loginButton": "Login",
"changePasswordTitle": "Change Password",
"changePasswordButton": "Change Password",
"passwordsMustMatch": "Passwords must match",
"changeSuccess": "Password changed successfully",
"invalidCredentials": "Invalid username or password"
},
"server": {
"addServer": "Add Server",
@@ -33,25 +40,34 @@
"delete": "Delete",
"confirmDelete": "Are you sure you want to delete this server?",
"status": "Status",
"tools": "Tools",
"name": "Server Name",
"url": "Server URL",
"tools": "Available Tools",
"name": "Name",
"url": "URL",
"apiKey": "API Key",
"save": "Save Changes",
"save": "Save",
"cancel": "Cancel",
"invalidConfig": "Could not find configuration data for {{serverName}}",
"invalidConfig": "Failed to get configuration for '{{serverName}}'",
"addError": "Failed to add server",
"editError": "Failed to edit server {{serverName}}",
"deleteError": "Failed to delete server {{serverName}}",
"updateError": "Failed to update server",
"updateError": "Failed to update server '{{serverName}}'",
"editTitle": "Edit Server: {{serverName}}",
"type": "Server Type",
"type": "Type",
"command": "Command",
"arguments": "Arguments",
"envVars": "Environment Variables",
"key": "key",
"value": "value",
"remove": "Remove"
"key": "Key",
"value": "Value",
"remove": "Remove",
"deleteTitle": "Delete Server",
"deleteConfirm": "Are you sure you want to delete {{serverName}}?",
"deleteWarning": "This action cannot be undone.",
"enable": "Enable",
"disable": "Disable",
"toggleError": "Failed to toggle server: {{serverName}}",
"invalidData": "Invalid server data",
"alreadyExists": "Server '{{serverName}}' already exists",
"notFound": "Server '{{serverName}}' not found"
},
"status": {
"online": "Online",
@@ -59,16 +75,17 @@
"connecting": "Connecting"
},
"errors": {
"general": "Something went wrong",
"network": "Network connection error. Please check your internet connection",
"serverConnection": "Unable to connect to the server. Please check if the server is running",
"serverAdd": "Failed to add server. Please check the server status",
"serverUpdate": "Failed to edit server {{serverName}}. Please check the server status",
"serverFetch": "Failed to retrieve server data. Please try again later",
"initialStartup": "The server might be starting up. Please wait a moment as this process can take some time on first launch..."
"general": "An error occurred",
"network": "Network connection error. Please check your internet connection.",
"serverConnection": "Could not connect to server. Please try again later.",
"serverAdd": "Failed to add server.",
"serverUpdate": "Failed to update server '{{serverName}}'.",
"serverFetch": "Failed to fetch servers data.",
"initialStartup": "Server is starting up. Please wait..."
},
"common": {
"save": "Save",
"cancel": "Cancel"
"cancel": "Cancel",
"processing": "Processing..."
}
}

View File

@@ -3,7 +3,7 @@
"title": "MCP Hub 控制面板",
"error": "错误",
"closeButton": "关闭",
"noServers": "没有可用的 MCP 服务器",
"noServers": "未找到服务器。添加新服务器以开始使用。",
"loading": "加载中...",
"logout": "退出登录",
"profile": "个人资料",
@@ -14,44 +14,60 @@
"loginTitle": "登录 MCP Hub",
"username": "用户名",
"password": "密码",
"loggingIn": "登录...",
"loggingIn": "正在登录...",
"emptyFields": "用户名和密码不能为空",
"loginFailed": "登录失败,请检查用户名和密码",
"loginError": "登录过程中出现错误",
"loginError": "登录时发生错误",
"currentPassword": "当前密码",
"newPassword": "新密码",
"confirmPassword": "确认密码",
"passwordsNotMatch": "新密码确认密码不一致",
"passwordsNotMatch": "新密码确认密码不匹配",
"changePasswordSuccess": "密码修改成功",
"changePasswordError": "修改密码失败",
"changePassword": "修改密码"
"changePasswordError": "密码修改失败",
"changePassword": "修改密码",
"confirmNewPassword": "确认新密码",
"loginButton": "登录",
"changePasswordTitle": "修改密码",
"changePasswordButton": "修改密码",
"passwordsMustMatch": "密码必须匹配",
"changeSuccess": "密码修改成功",
"invalidCredentials": "用户名或密码无效"
},
"server": {
"addServer": "添加服务器",
"add": "添加",
"edit": "编辑",
"delete": "删除",
"confirmDelete": "确定要删除此服务器吗?",
"confirmDelete": "确定要删除此服务器吗?",
"status": "状态",
"tools": "工具",
"name": "服务器名称",
"url": "服务器 URL",
"tools": "可用工具",
"name": "名称",
"url": "URL",
"apiKey": "API 密钥",
"save": "保存更改",
"save": "保存",
"cancel": "取消",
"invalidConfig": "获取 '{{serverName}}' 的配置失败",
"addError": "添加服务器失败",
"editError": "编辑服务器 {{serverName}} 失败",
"invalidConfig": "无法找到 {{serverName}} 的配置数据",
"deleteError": "删除服务器 {{serverName}} 失败",
"updateError": "更新服务器失败",
"updateError": "更新服务器 '{{serverName}}' 失败",
"editTitle": "编辑服务器: {{serverName}}",
"type": "服务器类型",
"type": "类型",
"command": "命令",
"arguments": "参数",
"envVars": "环境变量",
"key": "键",
"value": "值",
"remove": "移除"
"remove": "移除",
"deleteTitle": "删除服务器",
"deleteConfirm": "您确定要删除 {{serverName}} 吗?",
"deleteWarning": "此操作无法撤销。",
"enable": "启用",
"disable": "禁用",
"toggleError": "切换服务器 {{serverName}} 状态失败",
"invalidData": "无效的服务器数据",
"alreadyExists": "服务器 '{{serverName}}' 已存在",
"notFound": "未找到服务器 '{{serverName}}'"
},
"status": {
"online": "在线",
@@ -60,15 +76,16 @@
},
"errors": {
"general": "发生错误",
"network": "网络连接错误请检查您的互联网连接",
"serverConnection": "无法连接到服务器,请检查服务器是否正在运行",
"serverAdd": "添加服务器失败,请检查服务器状态",
"serverUpdate": "编辑服务器 {{serverName}} 失败,请检查服务器状态",
"serverFetch": "获取服务器数据失败,请稍后重试",
"initialStartup": "服务器可能正在启动中。首次启动可能需要一些时间,请耐心等候..."
"network": "网络连接错误请检查您的互联网连接",
"serverConnection": "无法连接到服务器。请稍后再试。",
"serverAdd": "添加服务器失败",
"serverUpdate": "更新服务器 '{{serverName}}' 失败",
"serverFetch": "获取服务器数据失败",
"initialStartup": "服务器正在启动。请稍候..."
},
"common": {
"save": "保存",
"cancel": "取消"
"cancel": "取消",
"processing": "处理中..."
}
}

View File

@@ -30,6 +30,7 @@ export interface Server {
status: ServerStatus;
tools?: Tool[];
config?: ServerConfig;
enabled?: boolean;
}
// 环境变量类型