mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-03-14 10:27:24 +00:00
feat: complete internationalization (i18n) for components
Implemented comprehensive i18n translation support for the following components: 1. GitSettings.jsx - Git configuration interface 2. ApiKeysSettings.jsx - API keys settings 3. CredentialsSettings.jsx - Credentials settings (GitHub tokens) 4. TasksSettings.jsx - TaskMaster task management settings 5. ChatInterface.jsx - Chat interface (major translation work) New translation files: - src/i18n/locales/en/chat.json - English chat interface translations - src/i18n/locales/zh-CN/chat.json - Chinese chat interface translations ChatInterface.jsx translations: - Code block copy buttons (Copy, Copied, Copy code) - Message type labels (User, Error, Tool, Claude, Cursor, Codex) - Tool settings tooltip - Search result display (pattern, in, results) - Codex permission modes (Default, Accept Edits, Bypass Permissions, Plan) - Input placeholder and hint text - Keyboard shortcut hints (Ctrl+Enter/Enter modes) - Command menu button i18n configuration updates: - Registered chat namespace in config.js - Extended settings.json translations (git, apiKeys, tasks, agents, mcpServers sections) 完成以下组件的 i18n 翻译工作: 1. GitSettings.jsx - Git 配置界面 2. ApiKeysSettings.jsx - API 密钥设置 3. CredentialsSettings.jsx - 凭据设置(GitHub Token) 4. TasksSettings.jsx - TaskMaster 任务管理设置 5. ChatInterface.jsx - 聊天界面(主要翻译工作) 新增翻译文件: - src/i18n/locales/en/chat.json - 英文聊天界面翻译 - src/i18n/locales/zh-CN/chat.json - 中文聊天界面翻译 ChatInterface.jsx 翻译内容: - 代码块复制按钮 - 消息类型标签 - 工具设置提示 - 搜索结果显示 - Codex 权限模式(默认、编辑、无限制、计划模式) - 输入框占位符和提示文本 - 键盘快捷键提示 - 命令菜单按钮 更新 i18n 配置: - 在 config.js 中注册 chat 命名空间 - 扩展 settings.json 翻译(git、apiKeys、tasks、agents、mcpServers 等部分)
This commit is contained in:
@@ -3,6 +3,7 @@ import { Button } from '../ui/button';
|
||||
import { Input } from '../ui/input';
|
||||
import { Badge } from '../ui/badge';
|
||||
import { Server, Plus, Edit3, Trash2, Terminal, Globe, Zap, X } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const getTransportIcon = (type) => {
|
||||
switch (type) {
|
||||
@@ -25,16 +26,17 @@ function ClaudeMcpServers({
|
||||
serverTools,
|
||||
toolsLoading,
|
||||
}) {
|
||||
const { t } = useTranslation('settings');
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Server className="w-5 h-5 text-purple-500" />
|
||||
<h3 className="text-lg font-medium text-foreground">
|
||||
MCP Servers
|
||||
{t('mcpServers.title')}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Model Context Protocol servers provide additional tools and data sources to Claude
|
||||
{t('mcpServers.description.claude')}
|
||||
</p>
|
||||
|
||||
<div className="flex justify-between items-center">
|
||||
@@ -44,7 +46,7 @@ function ClaudeMcpServers({
|
||||
size="sm"
|
||||
>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Add MCP Server
|
||||
{t('mcpServers.addButton')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -60,19 +62,19 @@ function ClaudeMcpServers({
|
||||
{server.type}
|
||||
</Badge>
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{server.scope === 'local' ? 'local' : server.scope === 'user' ? 'user' : server.scope}
|
||||
{server.scope === 'local' ? t('mcpServers.scope.local') : server.scope === 'user' ? t('mcpServers.scope.user') : server.scope}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div className="text-sm text-muted-foreground space-y-1">
|
||||
{server.type === 'stdio' && server.config?.command && (
|
||||
<div>Command: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.command}</code></div>
|
||||
<div>{t('mcpServers.config.command')}: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.command}</code></div>
|
||||
)}
|
||||
{(server.type === 'sse' || server.type === 'http') && server.config?.url && (
|
||||
<div>URL: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.url}</code></div>
|
||||
<div>{t('mcpServers.config.url')}: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.url}</code></div>
|
||||
)}
|
||||
{server.config?.args && server.config.args.length > 0 && (
|
||||
<div>Args: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.args.join(' ')}</code></div>
|
||||
<div>{t('mcpServers.config.args')}: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.args.join(' ')}</code></div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -90,13 +92,13 @@ function ClaudeMcpServers({
|
||||
{/* Tools Discovery Results */}
|
||||
{serverTools?.[server.id] && serverTools[server.id].tools?.length > 0 && (
|
||||
<div className="mt-2 p-2 rounded text-xs bg-blue-50 dark:bg-blue-900/20 text-blue-800 dark:text-blue-200">
|
||||
<div className="font-medium">Tools ({serverTools[server.id].tools.length}):</div>
|
||||
<div className="font-medium">{t('mcpServers.tools.title')} {t('mcpServers.tools.count', { count: serverTools[server.id].tools.length })}</div>
|
||||
<div className="flex flex-wrap gap-1 mt-1">
|
||||
{serverTools[server.id].tools.slice(0, 5).map((tool, i) => (
|
||||
<code key={i} className="bg-blue-100 dark:bg-blue-800 px-1 rounded">{tool.name}</code>
|
||||
))}
|
||||
{serverTools[server.id].tools.length > 5 && (
|
||||
<span className="text-xs opacity-75">+{serverTools[server.id].tools.length - 5} more</span>
|
||||
<span className="text-xs opacity-75">{t('mcpServers.tools.more', { count: serverTools[server.id].tools.length - 5 })}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -109,7 +111,7 @@ function ClaudeMcpServers({
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-gray-600 hover:text-gray-700"
|
||||
title="Edit server"
|
||||
title={t('mcpServers.actions.edit')}
|
||||
>
|
||||
<Edit3 className="w-4 h-4" />
|
||||
</Button>
|
||||
@@ -118,7 +120,7 @@ function ClaudeMcpServers({
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-red-600 hover:text-red-700"
|
||||
title="Delete server"
|
||||
title={t('mcpServers.actions.delete')}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</Button>
|
||||
@@ -128,7 +130,7 @@ function ClaudeMcpServers({
|
||||
))}
|
||||
{servers.length === 0 && (
|
||||
<div className="text-center py-8 text-gray-500 dark:text-gray-400">
|
||||
No MCP servers configured
|
||||
{t('mcpServers.empty')}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -138,16 +140,17 @@ function ClaudeMcpServers({
|
||||
|
||||
// Cursor MCP Servers
|
||||
function CursorMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
const { t } = useTranslation('settings');
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Server className="w-5 h-5 text-purple-500" />
|
||||
<h3 className="text-lg font-medium text-foreground">
|
||||
MCP Servers
|
||||
{t('mcpServers.title')}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Model Context Protocol servers provide additional tools and data sources to Cursor
|
||||
{t('mcpServers.description.cursor')}
|
||||
</p>
|
||||
|
||||
<div className="flex justify-between items-center">
|
||||
@@ -157,7 +160,7 @@ function CursorMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
size="sm"
|
||||
>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Add MCP Server
|
||||
{t('mcpServers.addButton')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -173,7 +176,7 @@ function CursorMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{server.config?.command && (
|
||||
<div>Command: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.command}</code></div>
|
||||
<div>{t('mcpServers.config.command')}: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.command}</code></div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -183,6 +186,7 @@ function CursorMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-gray-600 hover:text-gray-700"
|
||||
title={t('mcpServers.actions.edit')}
|
||||
>
|
||||
<Edit3 className="w-4 h-4" />
|
||||
</Button>
|
||||
@@ -191,6 +195,7 @@ function CursorMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-red-600 hover:text-red-700"
|
||||
title={t('mcpServers.actions.delete')}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</Button>
|
||||
@@ -200,7 +205,7 @@ function CursorMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
))}
|
||||
{servers.length === 0 && (
|
||||
<div className="text-center py-8 text-gray-500 dark:text-gray-400">
|
||||
No MCP servers configured
|
||||
{t('mcpServers.empty')}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -210,16 +215,17 @@ function CursorMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
|
||||
// Codex MCP Servers
|
||||
function CodexMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
const { t } = useTranslation('settings');
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Server className="w-5 h-5 text-gray-700 dark:text-gray-300" />
|
||||
<h3 className="text-lg font-medium text-foreground">
|
||||
MCP Servers
|
||||
{t('mcpServers.title')}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Model Context Protocol servers provide additional tools and data sources to Codex
|
||||
{t('mcpServers.description.codex')}
|
||||
</p>
|
||||
|
||||
<div className="flex justify-between items-center">
|
||||
@@ -229,7 +235,7 @@ function CodexMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
size="sm"
|
||||
>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Add MCP Server
|
||||
{t('mcpServers.addButton')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -246,13 +252,13 @@ function CodexMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
|
||||
<div className="text-sm text-muted-foreground space-y-1">
|
||||
{server.config?.command && (
|
||||
<div>Command: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.command}</code></div>
|
||||
<div>{t('mcpServers.config.command')}: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.command}</code></div>
|
||||
)}
|
||||
{server.config?.args && server.config.args.length > 0 && (
|
||||
<div>Args: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.args.join(' ')}</code></div>
|
||||
<div>{t('mcpServers.config.args')}: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{server.config.args.join(' ')}</code></div>
|
||||
)}
|
||||
{server.config?.env && Object.keys(server.config.env).length > 0 && (
|
||||
<div>Environment: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{Object.entries(server.config.env).map(([k, v]) => `${k}=${v}`).join(', ')}</code></div>
|
||||
<div>{t('mcpServers.config.environment')}: <code className="bg-gray-100 dark:bg-gray-800 px-1 rounded text-xs">{Object.entries(server.config.env).map(([k, v]) => `${k}=${v}`).join(', ')}</code></div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -263,7 +269,7 @@ function CodexMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-gray-600 hover:text-gray-700"
|
||||
title="Edit server"
|
||||
title={t('mcpServers.actions.edit')}
|
||||
>
|
||||
<Edit3 className="w-4 h-4" />
|
||||
</Button>
|
||||
@@ -272,7 +278,7 @@ function CodexMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-red-600 hover:text-red-700"
|
||||
title="Delete server"
|
||||
title={t('mcpServers.actions.delete')}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</Button>
|
||||
@@ -282,17 +288,16 @@ function CodexMcpServers({ servers, onAdd, onEdit, onDelete }) {
|
||||
))}
|
||||
{servers.length === 0 && (
|
||||
<div className="text-center py-8 text-gray-500 dark:text-gray-400">
|
||||
No MCP servers configured
|
||||
{t('mcpServers.empty')}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Help Section */}
|
||||
<div className="bg-gray-100 dark:bg-gray-800/50 border border-gray-300 dark:border-gray-600 rounded-lg p-4">
|
||||
<h4 className="font-medium text-gray-900 dark:text-gray-100 mb-2">About Codex MCP</h4>
|
||||
<h4 className="font-medium text-gray-900 dark:text-gray-100 mb-2">{t('mcpServers.help.title')}</h4>
|
||||
<p className="text-sm text-gray-700 dark:text-gray-300">
|
||||
Codex supports stdio-based MCP servers. You can add servers that extend Codex's capabilities
|
||||
with additional tools and resources.
|
||||
{t('mcpServers.help.description')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user