修复 i18n
This commit is contained in:
@@ -150,11 +150,11 @@ export const AgentsModal: React.FC<AgentsModalProps> = ({ open, onOpenChange })
|
||||
if (filePath) {
|
||||
const agent = await api.importAgentFromFile(filePath as string);
|
||||
loadAgents(); // Refresh list
|
||||
setToast({ message: `Agent "${agent.name}" imported successfully`, type: "success" });
|
||||
setToast({ message: t('agents.importedSuccessfully', { name: agent.name }), type: "success" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to import agent:', error);
|
||||
setToast({ message: "Failed to import agent", type: "error" });
|
||||
setToast({ message: t('agents.importFailed'), type: "error" });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -175,11 +175,11 @@ export const AgentsModal: React.FC<AgentsModalProps> = ({ open, onOpenChange })
|
||||
|
||||
if (filePath) {
|
||||
await invoke('write_file', { path: filePath, content: JSON.stringify(exportData, null, 2) });
|
||||
setToast({ message: "Agent exported successfully", type: "success" });
|
||||
setToast({ message: t('agents.exportedSuccessfully', { name: agent.name }), type: "success" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to export agent:', error);
|
||||
setToast({ message: "Failed to export agent", type: "error" });
|
||||
setToast({ message: t('agents.exportFailed'), type: "error" });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -424,7 +424,7 @@ export const AgentsModal: React.FC<AgentsModalProps> = ({ open, onOpenChange })
|
||||
onImportSuccess={() => {
|
||||
setShowGitHubBrowser(false);
|
||||
loadAgents(); // Refresh the agents list
|
||||
setToast({ message: "Agent imported successfully", type: "success" });
|
||||
setToast({ message: t('agents.importedSuccessfully'), type: "success" });
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
@@ -7,12 +7,14 @@ import { Badge } from "@/components/ui/badge";
|
||||
import { Toast, ToastContainer } from "@/components/ui/toast";
|
||||
import { ccrApi, type CcrServiceStatus } from "@/lib/api";
|
||||
import { open } from '@tauri-apps/plugin-shell';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
|
||||
interface CcrRouterManagerProps {
|
||||
onBack: () => void;
|
||||
}
|
||||
|
||||
export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
const { t } = useTranslation();
|
||||
const [serviceStatus, setServiceStatus] = useState<CcrServiceStatus | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [actionLoading, setActionLoading] = useState(false);
|
||||
@@ -34,7 +36,7 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
} catch (error) {
|
||||
console.error("Failed to load CCR service status:", error);
|
||||
setToast({
|
||||
message: `加载CCR服务状态失败: ${error}`,
|
||||
message: t('ccr.loadStatusFailed', { error: String(error) }),
|
||||
type: "error"
|
||||
});
|
||||
} finally {
|
||||
@@ -63,7 +65,7 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
} catch (error) {
|
||||
console.error("Failed to start CCR service:", error);
|
||||
setToast({
|
||||
message: `启动CCR服务失败: ${error}`,
|
||||
message: t('ccr.startFailed', { error: String(error) }),
|
||||
type: "error"
|
||||
});
|
||||
} finally {
|
||||
@@ -83,7 +85,7 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
} catch (error) {
|
||||
console.error("Failed to stop CCR service:", error);
|
||||
setToast({
|
||||
message: `停止CCR服务失败: ${error}`,
|
||||
message: t('ccr.stopFailed', { error: String(error) }),
|
||||
type: "error"
|
||||
});
|
||||
} finally {
|
||||
@@ -103,7 +105,7 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
} catch (error) {
|
||||
console.error("Failed to restart CCR service:", error);
|
||||
setToast({
|
||||
message: `重启CCR服务失败: ${error}`,
|
||||
message: t('ccr.restartFailed', { error: String(error) }),
|
||||
type: "error"
|
||||
});
|
||||
} finally {
|
||||
@@ -118,14 +120,14 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
// 如果服务未运行,先尝试启动
|
||||
if (!serviceStatus?.is_running) {
|
||||
setToast({
|
||||
message: "检测到服务未运行,正在启动...",
|
||||
message: t('ccr.serviceStarting'),
|
||||
type: "info"
|
||||
});
|
||||
const startResult = await ccrApi.startService();
|
||||
setServiceStatus(startResult.status);
|
||||
|
||||
if (!startResult.status.is_running) {
|
||||
throw new Error("服务启动失败");
|
||||
throw new Error(t('ccr.serviceStartFailed'));
|
||||
}
|
||||
|
||||
// 等待服务完全启动
|
||||
@@ -134,7 +136,7 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
|
||||
await ccrApi.openUI();
|
||||
setToast({
|
||||
message: "正在打开CCR UI...",
|
||||
message: t('ccr.openingUI'),
|
||||
type: "info"
|
||||
});
|
||||
|
||||
@@ -145,7 +147,7 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
} catch (error) {
|
||||
console.error("Failed to open CCR UI:", error);
|
||||
setToast({
|
||||
message: `打开CCR UI失败: ${error}`,
|
||||
message: t('ccr.openUIFailed', { error: String(error) }),
|
||||
type: "error"
|
||||
});
|
||||
} finally {
|
||||
@@ -159,7 +161,7 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
if (!serviceStatus?.is_running) {
|
||||
setActionLoading(true);
|
||||
setToast({
|
||||
message: "检测到服务未运行,正在启动...",
|
||||
message: t('ccr.serviceStarting'),
|
||||
type: "info"
|
||||
});
|
||||
|
||||
@@ -167,7 +169,7 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
setServiceStatus(startResult.status);
|
||||
|
||||
if (!startResult.status.is_running) {
|
||||
throw new Error("服务启动失败");
|
||||
throw new Error(t('ccr.serviceStartFailed'));
|
||||
}
|
||||
|
||||
// 等待服务完全启动
|
||||
@@ -178,14 +180,14 @@ export function CcrRouterManager({ onBack }: CcrRouterManagerProps) {
|
||||
if (serviceStatus?.endpoint) {
|
||||
open(`${serviceStatus.endpoint}/ui/`);
|
||||
setToast({
|
||||
message: "正在打开CCR管理界面...",
|
||||
message: t('ccr.openingAdmin'),
|
||||
type: "info"
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to open CCR UI in browser:", error);
|
||||
setToast({
|
||||
message: `打开管理界面失败: ${error}`,
|
||||
message: t('ccr.openAdminFailed', { error: String(error) }),
|
||||
type: "error"
|
||||
});
|
||||
setActionLoading(false);
|
||||
|
||||
@@ -1519,7 +1519,7 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>滚动到顶部</p>
|
||||
<p>{t('claudeSession.scrollToTop', 'Scroll to top')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
@@ -1540,7 +1540,7 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>滚动到底部</p>
|
||||
<p>{t('claudeSession.scrollToBottom', 'Scroll to bottom')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
@@ -1665,7 +1665,7 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
<div className="flex items-center gap-1.5 text-xs bg-muted/50 rounded-full px-2.5 py-1">
|
||||
<Hash className="h-3 w-3 text-muted-foreground" />
|
||||
<span className="font-mono">{totalTokens.toLocaleString()}</span>
|
||||
<span className="text-muted-foreground">tokens</span>
|
||||
<span className="text-muted-foreground">{t('usage.tokens')}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1705,7 +1705,7 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>File Explorer</p>
|
||||
<p>{t('app.fileExplorer')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
@@ -1726,7 +1726,7 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Git Panel</p>
|
||||
<p>{t('app.gitPanel')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
@@ -1747,7 +1747,7 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>{isFileWatching ? '停止文件监控' : '启动文件监控'}</p>
|
||||
<p>{isFileWatching ? t('claudeSession.stopFileWatch', 'Stop file watching') : t('claudeSession.startFileWatch', 'Start file watching')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
|
||||
@@ -136,7 +136,7 @@ export const Settings: React.FC<SettingsProps> = ({
|
||||
setModelMappings(mappings);
|
||||
} catch (err) {
|
||||
console.error("Failed to load model mappings:", err);
|
||||
setToast({ message: "加载模型映射失败", type: "error" });
|
||||
setToast({ message: t('settings.modelMappings.loadFailed'), type: "error" });
|
||||
} finally {
|
||||
setLoadingMappings(false);
|
||||
}
|
||||
@@ -163,10 +163,10 @@ export const Settings: React.FC<SettingsProps> = ({
|
||||
await api.updateModelMapping(mapping.alias, mapping.model_name);
|
||||
}
|
||||
setModelMappingsChanged(false);
|
||||
setToast({ message: "模型映射已保存", type: "success" });
|
||||
setToast({ message: t('settings.modelMappings.saved'), type: "success" });
|
||||
} catch (err) {
|
||||
console.error("Failed to save model mappings:", err);
|
||||
setToast({ message: "保存模型映射失败", type: "error" });
|
||||
setToast({ message: t('settings.modelMappings.saveFailed'), type: "error" });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -696,9 +696,9 @@ export const Settings: React.FC<SettingsProps> = ({
|
||||
{/* Model Mappings Configuration */}
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label className="text-sm font-medium mb-2 block">模型别名映射</Label>
|
||||
<Label className="text-sm font-medium mb-2 block">{t('settings.modelMappings.title')}</Label>
|
||||
<p className="text-xs text-muted-foreground mb-4">
|
||||
配置模型别名(sonnet、opus、haiku)对应的实际模型版本
|
||||
{t('settings.modelMappings.description')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -720,29 +720,29 @@ export const Settings: React.FC<SettingsProps> = ({
|
||||
className="font-mono text-sm"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{mapping.alias === 'sonnet' && '平衡性能与成本的主力模型'}
|
||||
{mapping.alias === 'opus' && '最强大的旗舰模型,适合复杂任务'}
|
||||
{mapping.alias === 'haiku' && '快速响应的轻量级模型'}
|
||||
{mapping.alias === 'sonnet' && t('settings.modelMappings.aliasDescriptions.sonnet')}
|
||||
{mapping.alias === 'opus' && t('settings.modelMappings.aliasDescriptions.opus')}
|
||||
{mapping.alias === 'haiku' && t('settings.modelMappings.aliasDescriptions.haiku')}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{modelMappings.length === 0 && (
|
||||
<div className="text-center py-8 text-muted-foreground">
|
||||
<p className="text-sm">暂无模型映射配置</p>
|
||||
<p className="text-xs mt-2">数据库初始化可能未完成,请尝试重启应用</p>
|
||||
<p className="text-sm">{t('settings.modelMappings.emptyTitle')}</p>
|
||||
<p className="text-xs mt-2">{t('settings.modelMappings.emptySubtitle')}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{modelMappingsChanged && (
|
||||
<p className="text-xs text-amber-600 dark:text-amber-400">
|
||||
模型映射已修改,点击保存以应用更改
|
||||
{t('settings.modelMappings.changedNotice')}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="pt-2">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<strong>说明:</strong>Agent执行时会根据这里的配置解析模型别名。例如,如果设置 sonnet → claude-sonnet-4-20250514,那么所有使用 "sonnet" 的Agent都会调用该模型版本。
|
||||
<strong>{t('settings.modelMappings.note')}</strong> {t('settings.modelMappings.noteContent')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -398,9 +398,11 @@ export const TabContent: React.FC = () => {
|
||||
console.log('[TabContent] Handling create-smart-session-tab:', { tabId, sessionData });
|
||||
|
||||
// Update the existing tab with smart session data and switch immediately
|
||||
const displayName = sessionData.display_name || t('smartSessionDefaultTitle');
|
||||
|
||||
updateTab(tabId, {
|
||||
type: 'chat',
|
||||
title: sessionData.display_name || 'Smart Session',
|
||||
title: displayName,
|
||||
initialProjectPath: sessionData.project_path,
|
||||
sessionData: null, // No existing session, this is a new session workspace
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user