feat(i18n): add internationalization support across multiple components

This commit is contained in:
2025-10-27 14:41:58 +08:00
parent 49742f6219
commit 46cc8a254a
23 changed files with 777 additions and 2623 deletions

View File

@@ -35,6 +35,7 @@ import McpDialog from '@/pages/setting/components/McpDialog';
import type { IMcpServer } from '@/interfaces/database/mcp';
import type { IImportMcpServersRequestBody, ICreateMcpServerRequestBody, ITestMcpRequestBody } from '@/interfaces/request/mcp';
import { useMessage } from '@/hooks/useSnackbar';
import { useTranslation } from 'react-i18next';
import dayjs from 'dayjs';
const PageContainer = styled(Box)(({ theme }) => ({
@@ -69,6 +70,7 @@ const SearchContainer = styled(Box)(({ theme }) => ({
export default function McpSettingPage() {
const { t } = useTranslation();
const handleRefreshServer = async (initial?: boolean) => {
if (initial) {
@@ -187,9 +189,9 @@ export default function McpSettingPage() {
if (selectedServerId) {
const result = await deleteMcpServer(selectedServerId);
if (result.success) {
showMessage.success('删除成功');
showMessage.success(t('mcp.deleteSuccess'));
} else {
showMessage.error(result.error || '删除失败');
showMessage.error(t('mcp.deleteFailed'));
}
}
handleMenuClose();
@@ -198,19 +200,19 @@ export default function McpSettingPage() {
const handleBulkDelete = async () => {
const result = await batchDeleteMcpServers(selectedServers);
if (result.success) {
showMessage.success('批量删除成功');
showMessage.success(t('mcp.batchDeleteSuccess'));
setSelectedServers([]);
} else {
showMessage.error(result.error || '批量删除失败');
showMessage.error(t('mcp.batchDeleteFailed'));
}
};
const handleExport = async () => {
const result = await exportMcpServers(selectedServers);
if (result.success) {
showMessage.success('导出成功');
showMessage.success(t('mcp.exportSuccess'));
} else {
showMessage.error(result.error || '导出失败');
showMessage.error(t('mcp.exportFailed'));
}
};
@@ -218,12 +220,12 @@ export default function McpSettingPage() {
try {
if (editingServer) {
if (!editingServer.id) {
showMessage.error('server id 不能为空');
showMessage.error(t('mcp.serverIdRequired'));
return { success: false, error: 'server id 不能为空' };
}
const result = await updateMcpServer({ ...data, mcp_id: editingServer.id ?? '' });
if (result.success) {
showMessage.success('MCP 服务器更新成功');
showMessage.success(t('mcp.mcpServerUpdateSuccess'));
setMcpDialogOpen(false);
setEditingServer(null);
return result;
@@ -233,7 +235,7 @@ export default function McpSettingPage() {
} else {
const result = await createMcpServer(data);
if (result.success) {
showMessage.success('MCP 服务器创建成功');
showMessage.success(t('mcp.mcpServerCreateSuccess'));
setMcpDialogOpen(false);
setEditingServer(null);
return result;
@@ -251,7 +253,7 @@ export default function McpSettingPage() {
try {
const result = await testMcpServer(data);
if (result.success) {
showMessage.success('测试成功');
showMessage.success(t('mcp.testSuccess'));
return result;
} else {
return result;
@@ -283,7 +285,7 @@ export default function McpSettingPage() {
setImportJson('');
}
} else {
showMessage.error('JSON 格式错误');
showMessage.error(t('mcp.jsonFormatError'));
}
} catch (error) {
showMessage.error('JSON 格式错误');
@@ -294,11 +296,11 @@ export default function McpSettingPage() {
<PageContainer>
<PageHeader>
<Box>
<Typography variant="h4" fontWeight={600} color="#333">
MCP Servers
<Typography variant="h5" component="h1" fontWeight="bold">
{t('mcp.mcpServers')}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
Customize the list of MCP servers
<Typography variant="body2" color="text.secondary">
{t('mcp.customizeTheListOfMcpServers')}
</Typography>
</Box>
<Box display="flex" gap={2}>
@@ -307,14 +309,14 @@ export default function McpSettingPage() {
startIcon={<ImportIcon />}
onClick={() => setImportDialogOpen(true)}
>
Import
{t('mcp.import')}
</Button>
<Button
variant="contained"
startIcon={<AddIcon />}
onClick={handleAdd}
>
Add MCP
{t('mcp.addMCP')}
</Button>
</Box>
</PageHeader>
@@ -323,7 +325,7 @@ export default function McpSettingPage() {
<Box>
<TextField
size="small"
placeholder="Search MCP servers..."
placeholder={t('mcp.searchPlaceholder')}
value={searchString}
onChange={handleSearchChange}
InputProps={{
@@ -338,16 +340,17 @@ export default function McpSettingPage() {
size="small"
startIcon={<DeleteIcon />}
onClick={handleBulkDelete}
color="error"
disabled={selectedServers.length === 0}
>
Delete ({selectedServers.length})
{t('mcp.deleteSelected')}
</Button>
<Button
size="small"
startIcon={<ExportIcon />}
onClick={handleExport}
disabled={selectedServers.length === 0}
>
Export ({selectedServers.length})
{t('mcp.exportSelected')}
</Button>
</Box>
)}
@@ -389,10 +392,10 @@ export default function McpSettingPage() {
{server.name}
</Typography>
<Typography variant="body2" color="text.secondary" gutterBottom>
: {server.server_type}
{t('mcp.type')}: {server.server_type}
</Typography>
<Typography variant="body2" color="text.secondary">
: {dayjs(server.update_date).format('YYYY-MM-DD HH:mm:ss')}
{t('mcp.updateTime')}: {dayjs(server.update_date).format('YYYY-MM-DD HH:mm:ss')}
</Typography>
</CardContent>
</Card>
@@ -409,7 +412,7 @@ export default function McpSettingPage() {
color="primary"
/>
<Typography variant="body2" sx={{ ml: 2 }}>
{total}
{t('mcp.totalItems', { count: total })}
</Typography>
</Box>
</>
@@ -423,11 +426,11 @@ export default function McpSettingPage() {
>
<MenuItem onClick={handleEdit}>
<EditIcon sx={{ mr: 1 }} fontSize="small" />
Edit
{t('common.edit')}
</MenuItem>
<MenuItem onClick={handleDelete} sx={{ color: 'error.main' }}>
<DeleteIcon sx={{ mr: 1 }} fontSize="small" />
Delete
{t('common.delete')}
</MenuItem>
</Menu>
@@ -446,16 +449,16 @@ export default function McpSettingPage() {
{/* 导入对话框 */}
<Dialog open={importDialogOpen} onClose={() => setImportDialogOpen(false)} maxWidth="md" fullWidth>
<DialogTitle>Import MCP Servers</DialogTitle>
<DialogTitle>{t('mcp.importTitle')}</DialogTitle>
<DialogContent>
<Alert severity="info" sx={{ mb: 2 }}>
Paste your MCP servers JSON configuration below. The format should match the Mock.json structure.
{t('mcp.importDescription')}
</Alert>
<TextField
fullWidth
multiline
rows={10}
label="JSON Configuration"
label={t('mcp.jsonConfiguration')}
value={importJson}
onChange={(e) => setImportJson(e.target.value)}
placeholder={`{
@@ -472,9 +475,9 @@ export default function McpSettingPage() {
/>
</DialogContent>
<DialogActions>
<Button onClick={() => setImportDialogOpen(false)}>Cancel</Button>
<Button onClick={() => setImportDialogOpen(false)}>{t('common.cancel')}</Button>
<Button onClick={handleImport} variant="contained">
Import
{t('mcp.import')}
</Button>
</DialogActions>
</Dialog>