feat(Localization): Add toggle error message for MCP servers across languages

- Update en-us, ja-jp, ru-ru, zh-cn, and zh-tw locale files
- Add 'toggleError' translation key for MCP server settings
- Improve error handling and user feedback for server toggle actions
This commit is contained in:
kangfenmao 2025-03-11 16:46:53 +08:00
parent 67bb1f19f0
commit a25c0e657b
6 changed files with 79 additions and 91 deletions

View File

@ -806,7 +806,8 @@
"title": "MCP Servers",
"type": "Type",
"updateSuccess": "Server updated successfully",
"url": "URL"
"url": "URL",
"toggleError": "Toggle failed"
},
"messages.divider": "Show divider between messages",
"messages.grid_columns": "Message grid display columns",

View File

@ -806,7 +806,8 @@
"title": "MCP サーバー",
"type": "タイプ",
"updateSuccess": "サーバーが正常に更新されました",
"url": "URL"
"url": "URL",
"toggleError": "切り替えに失敗しました"
},
"messages.divider": "メッセージ間に区切り線を表示",
"messages.grid_columns": "メッセージグリッドの表示列数",

View File

@ -806,7 +806,8 @@
"title": "Серверы MCP",
"type": "Тип",
"updateSuccess": "Сервер успешно обновлен",
"url": "URL"
"url": "URL",
"toggleError": "Переключение не удалось"
},
"messages.divider": "Показывать разделитель между сообщениями",
"messages.grid_columns": "Количество столбцов сетки сообщений",

View File

@ -806,7 +806,8 @@
"title": "MCP 服务器",
"type": "类型",
"updateSuccess": "服务器更新成功",
"url": "URL"
"url": "URL",
"toggleError": "切换失败"
},
"messages.divider": "消息分割线",
"messages.grid_columns": "消息网格展示列数",

View File

@ -806,7 +806,8 @@
"title": "MCP 伺服器",
"type": "類型",
"updateSuccess": "伺服器更新成功",
"url": "URL"
"url": "URL",
"toggleError": "切換失敗"
},
"messages.divider": "訊息間顯示分隔線",
"messages.grid_columns": "訊息網格展示列數",

View File

@ -1,7 +1,6 @@
import { DeleteOutlined, EditOutlined, PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useAppDispatch, useAppSelector } from '@renderer/store'
import { addMCPServer, deleteMCPServer, setMCPServerActive, updateMCPServer } from '@renderer/store/mcp'
import { useAppSelector } from '@renderer/store'
import { MCPServer } from '@renderer/types'
import { Button, Card, Form, Input, Modal, Radio, Space, Switch, Table, Tag, Tooltip, Typography } from 'antd'
import TextArea from 'antd/es/input/TextArea'
@ -25,7 +24,6 @@ const MCPSettings: FC = () => {
const { t } = useTranslation()
const { theme } = useTheme()
const { Paragraph, Text } = Typography
const dispatch = useAppDispatch()
const mcpServers = useAppSelector((state) => state.mcp.servers)
const [isModalVisible, setIsModalVisible] = useState(false)
@ -78,77 +76,69 @@ const MCPSettings: FC = () => {
form.resetFields()
}
const handleSubmit = () => {
const handleSubmit = async () => {
setLoading(true)
form
.validateFields()
.then((values) => {
const mcpServer: MCPServer = {
name: values.name,
description: values.description,
isActive: values.isActive
}
try {
const values = await form.validateFields()
const mcpServer: MCPServer = {
name: values.name,
description: values.description,
isActive: values.isActive
}
if (values.serverType === 'sse') {
mcpServer.baseUrl = values.baseUrl
} else {
mcpServer.command = values.command
mcpServer.args = values.args ? values.args.split('\n').filter((arg) => arg.trim() !== '') : []
if (values.serverType === 'sse') {
mcpServer.baseUrl = values.baseUrl
} else {
mcpServer.command = values.command
mcpServer.args = values.args ? values.args.split('\n').filter((arg) => arg.trim() !== '') : []
const env: Record<string, string> = {}
if (values.env) {
values.env.split('\n').forEach((line) => {
if (line.trim()) {
const [key, value] = line.split('=')
if (key && value) {
env[key.trim()] = value.trim()
}
const env: Record<string, string> = {}
if (values.env) {
values.env.split('\n').forEach((line) => {
if (line.trim()) {
const [key, value] = line.split('=')
if (key && value) {
env[key.trim()] = value.trim()
}
})
}
mcpServer.env = Object.keys(env).length > 0 ? env : undefined
}
})
}
mcpServer.env = Object.keys(env).length > 0 ? env : undefined
}
if (editingServer) {
try {
await window.api.mcp.updateServer(mcpServer)
window.message.success(t('settings.mcp.updateSuccess'))
setLoading(false)
setIsModalVisible(false)
form.resetFields()
} catch (error: any) {
window.message.error(`${t('settings.mcp.updateError')}: ${error.message}`)
setLoading(false)
}
} else {
// Check for duplicate name
if (mcpServers.some((server: MCPServer) => server.name === mcpServer.name)) {
window.message.error(t('settings.mcp.duplicateName'))
setLoading(false)
return
}
if (editingServer) {
window.api.mcp
.updateServer(mcpServer)
.then(() => {
window.message.success(t('settings.mcp.updateSuccess'))
setLoading(false)
setIsModalVisible(false)
form.resetFields()
})
.catch((error) => {
window.message.error(`${t('settings.mcp.updateError')}: ${error.message}`)
setLoading(false)
})
dispatch(updateMCPServer(mcpServer))
} else {
// Check for duplicate name
if (mcpServers.some((server: MCPServer) => server.name === mcpServer.name)) {
window.message.error(t('settings.mcp.duplicateName'))
setLoading(false)
return
}
window.api.mcp
.addServer(mcpServer)
.then(() => {
dispatch(addMCPServer(mcpServer))
window.message.success(t('settings.mcp.addSuccess'))
setLoading(false)
setIsModalVisible(false)
form.resetFields()
})
.catch((error) => {
window.message.error(`${t('settings.mcp.addError')}: ${error.message}`)
setLoading(false)
})
try {
await window.api.mcp.addServer(mcpServer)
window.message.success(t('settings.mcp.addSuccess'))
setLoading(false)
setIsModalVisible(false)
form.resetFields()
} catch (error: any) {
window.message.error(`${t('settings.mcp.addError')}: ${error.message}`)
setLoading(false)
}
})
.catch(() => {
setLoading(false)
})
}
} catch (error: any) {
setLoading(false)
}
}
const handleDelete = (serverName: string) => {
@ -159,30 +149,23 @@ const MCPSettings: FC = () => {
okButtonProps: { danger: true },
cancelText: t('common.cancel'),
centered: true,
onOk: () => {
window.api.mcp
.deleteServer(serverName)
.then(() => {
window.message.success(t('settings.mcp.deleteSuccess'))
})
.catch((error) => {
window.message.error(`${t('settings.mcp.deleteError')}: ${error.message}`)
})
dispatch(deleteMCPServer(serverName))
onOk: async () => {
try {
await window.api.mcp.deleteServer(serverName)
window.message.success(t('settings.mcp.deleteSuccess'))
} catch (error: any) {
window.message.error(`${t('settings.mcp.deleteError')}: ${error.message}`)
}
}
})
}
const handleToggleActive = (name: string, isActive: boolean) => {
window.api.mcp
.setServerActive(name, isActive)
.then(() => {
// Optional: Show success message or update UI
})
.catch((error) => {
window.message.error(`${t('settings.mcp.toggleError')}: ${error.message}`)
})
dispatch(setMCPServerActive({ name, isActive }))
try {
window.api.mcp.setServerActive(name, isActive)
} catch (error: any) {
window.message.error(`${t('settings.mcp.toggleError')}: ${error.message}`)
}
}
const columns = [