fix(i18n): add missing translation keys for deeplink confirmation components

- Add i18n support to McpConfirmation, PromptConfirmation, SkillConfirmation
- Add nested translation keys: deeplink.mcp.*, deeplink.prompt.*, deeplink.skill.*
- Replace all hardcoded Chinese strings with t() function calls
- Ensure consistent localization across all deeplink import dialogs
This commit is contained in:
Jason
2025-11-25 09:52:19 +08:00
parent 60fa9654e1
commit fd46dde3fb
5 changed files with 75 additions and 21 deletions
+8 -4
View File
@@ -1,4 +1,5 @@
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { DeepLinkImportRequest } from "../../lib/api/deeplink";
import { decodeBase64Utf8 } from "../../lib/utils/base64";
@@ -7,6 +8,8 @@ export function McpConfirmation({
}: {
request: DeepLinkImportRequest;
}) {
const { t } = useTranslation();
const mcpServers = useMemo(() => {
if (!request.config) return null;
try {
@@ -20,14 +23,15 @@ export function McpConfirmation({
}, [request.config]);
const targetApps = request.apps?.split(",") || [];
const serverCount = Object.keys(mcpServers || {}).length;
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold"> MCP Servers</h3>
<h3 className="text-lg font-semibold">{t("deeplink.mcp.title")}</h3>
<div>
<label className="block text-sm font-medium text-muted-foreground">
{t("deeplink.mcp.targetApps")}
</label>
<div className="mt-1 flex gap-2 flex-wrap">
{targetApps.map((app) => (
@@ -43,7 +47,7 @@ export function McpConfirmation({
<div>
<label className="block text-sm font-medium text-muted-foreground">
MCP Servers ({Object.keys(mcpServers || {}).length} )
{t("deeplink.mcp.serverCount", { count: serverCount })}
</label>
<div className="mt-1 space-y-2 max-h-64 overflow-auto border rounded p-2 bg-muted/30">
{mcpServers &&
@@ -63,7 +67,7 @@ export function McpConfirmation({
{request.enabled && (
<div className="text-yellow-600 dark:text-yellow-500 text-sm flex items-center gap-2">
<span></span>
<span></span>
<span>{t("deeplink.mcp.enabledWarning")}</span>
</div>
)}
</div>
@@ -1,4 +1,5 @@
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { DeepLinkImportRequest } from "../../lib/api/deeplink";
import { decodeBase64Utf8 } from "../../lib/utils/base64";
@@ -7,6 +8,8 @@ export function PromptConfirmation({
}: {
request: DeepLinkImportRequest;
}) {
const { t } = useTranslation();
const decodedContent = useMemo(() => {
if (!request.content) return "";
return decodeBase64Utf8(request.content);
@@ -14,18 +17,18 @@ export function PromptConfirmation({
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold"></h3>
<h3 className="text-lg font-semibold">{t("deeplink.prompt.title")}</h3>
<div>
<label className="block text-sm font-medium text-muted-foreground">
{t("deeplink.prompt.app")}
</label>
<div className="mt-1 text-sm capitalize">{request.app}</div>
</div>
<div>
<label className="block text-sm font-medium text-muted-foreground">
{t("deeplink.prompt.name")}
</label>
<div className="mt-1 text-sm">{request.name}</div>
</div>
@@ -33,7 +36,7 @@ export function PromptConfirmation({
{request.description && (
<div>
<label className="block text-sm font-medium text-muted-foreground">
{t("deeplink.prompt.description")}
</label>
<div className="mt-1 text-sm">{request.description}</div>
</div>
@@ -41,7 +44,7 @@ export function PromptConfirmation({
<div>
<label className="block text-sm font-medium text-muted-foreground">
{t("deeplink.prompt.contentPreview")}
</label>
<pre className="mt-1 max-h-48 overflow-auto bg-muted/50 p-2 rounded text-xs whitespace-pre-wrap border">
{decodedContent.substring(0, 500)}
@@ -52,7 +55,7 @@ export function PromptConfirmation({
{request.enabled && (
<div className="text-yellow-600 dark:text-yellow-500 text-sm flex items-center gap-2">
<span></span>
<span></span>
<span>{t("deeplink.prompt.enabledWarning")}</span>
</div>
)}
</div>
+10 -9
View File
@@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import { DeepLinkImportRequest } from "../../lib/api/deeplink";
export function SkillConfirmation({
@@ -5,13 +6,15 @@ export function SkillConfirmation({
}: {
request: DeepLinkImportRequest;
}) {
const { t } = useTranslation();
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold"> Claude Skill </h3>
<h3 className="text-lg font-semibold">{t("deeplink.skill.title")}</h3>
<div>
<label className="block text-sm font-medium text-muted-foreground">
GitHub
{t("deeplink.skill.repo")}
</label>
<div className="mt-1 text-sm font-mono bg-muted/50 p-2 rounded border">
{request.repo}
@@ -20,7 +23,7 @@ export function SkillConfirmation({
<div>
<label className="block text-sm font-medium text-muted-foreground">
{t("deeplink.skill.directory")}
</label>
<div className="mt-1 text-sm font-mono bg-muted/50 p-2 rounded border">
{request.directory}
@@ -30,7 +33,7 @@ export function SkillConfirmation({
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-muted-foreground">
{t("deeplink.skill.branch")}
</label>
<div className="mt-1 text-sm">{request.branch || "main"}</div>
</div>
@@ -38,7 +41,7 @@ export function SkillConfirmation({
{request.skillsPath && (
<div>
<label className="block text-sm font-medium text-muted-foreground">
Skills
{t("deeplink.skill.skillsPath")}
</label>
<div className="mt-1 text-sm">{request.skillsPath}</div>
</div>
@@ -46,10 +49,8 @@ export function SkillConfirmation({
</div>
<div className="text-blue-600 dark:text-blue-400 text-sm bg-blue-50 dark:bg-blue-950/30 p-3 rounded border border-blue-200 dark:border-blue-800">
<p> Skill </p>
<p className="mt-1">
Skills Skill
</p>
<p> {t("deeplink.skill.hint")}</p>
<p className="mt-1">{t("deeplink.skill.hintDetail")}</p>
</div>
</div>
);
+24 -1
View File
@@ -787,7 +787,30 @@
"configRemote": "Remote Config",
"configDetails": "Config Details",
"configUrl": "Config File URL",
"configMergeError": "Failed to merge configuration file"
"configMergeError": "Failed to merge configuration file",
"mcp": {
"title": "Batch Import MCP Servers",
"targetApps": "Target Apps",
"serverCount": "MCP Servers ({{count}})",
"enabledWarning": "After import, configurations will be written to all specified apps immediately"
},
"prompt": {
"title": "Import System Prompt",
"app": "App",
"name": "Name",
"description": "Description",
"contentPreview": "Content Preview",
"enabledWarning": "After import, this prompt will be enabled immediately and other prompts will be disabled"
},
"skill": {
"title": "Add Claude Skill Repository",
"repo": "GitHub Repository",
"directory": "Target Directory",
"branch": "Branch",
"skillsPath": "Skills Path",
"hint": "This will add the Skill repository to the list.",
"hintDetail": "After adding, you can install specific Skills from the Skills management page."
}
},
"iconPicker": {
"search": "Search Icons",
+24 -1
View File
@@ -787,7 +787,30 @@
"configRemote": "远程配置",
"configDetails": "配置详情",
"configUrl": "配置文件 URL",
"configMergeError": "合并配置文件失败"
"configMergeError": "合并配置文件失败",
"mcp": {
"title": "批量导入 MCP Servers",
"targetApps": "目标应用",
"serverCount": "MCP Servers ({{count}} 个)",
"enabledWarning": "导入后将立即写入所有指定应用的配置文件"
},
"prompt": {
"title": "导入系统提示词",
"app": "应用",
"name": "名称",
"description": "描述",
"contentPreview": "内容预览",
"enabledWarning": "导入后将立即启用此提示词,其他提示词将被禁用"
},
"skill": {
"title": "添加 Claude Skill 仓库",
"repo": "GitHub 仓库",
"directory": "目标目录",
"branch": "分支",
"skillsPath": "Skills 路径",
"hint": "此操作将添加 Skill 仓库到列表。",
"hintDetail": "添加后,您可以在 Skills 管理界面中选择安装具体的 Skill。"
}
},
"iconPicker": {
"search": "搜索图标",