fix(i18n): correct interpolation syntax and add missing translation keys

- Fix i18next interpolation from {var} to {{var}} format in en.json
  - Add gemini_base_url_label translation key for better form labeling
  - Add virtual auth file and model list related translations
  - Adjust UsagePage title font size to 28px for consistency
This commit is contained in:
Supra4E8C
2025-12-14 23:44:25 +08:00
parent 09c17c03b9
commit 340c1f1ae5
4 changed files with 55 additions and 43 deletions

View File

@@ -137,17 +137,18 @@
"gemini_item_title": "Gemini Key", "gemini_item_title": "Gemini Key",
"gemini_add_modal_title": "Add Gemini API Key", "gemini_add_modal_title": "Add Gemini API Key",
"gemini_add_modal_key_label": "API Keys:", "gemini_add_modal_key_label": "API Keys:",
"gemini_add_modal_key_placeholder": "Enter Gemini API key", "gemini_add_modal_key_placeholder": "Enter Gemini API key",
"gemini_add_modal_key_hint": "Add keys one by one and optionally specify a Base URL.", "gemini_add_modal_key_hint": "Add keys one by one and optionally specify a Base URL.",
"gemini_keys_add_btn": "Add Key", "gemini_keys_add_btn": "Add Key",
"gemini_base_url_placeholder": "Optional Base URL, e.g. https://generativelanguage.googleapis.com", "gemini_base_url_label": "Base URL (Optional):",
"gemini_edit_modal_title": "Edit Gemini API Key", "gemini_base_url_placeholder": "e.g.: https://generativelanguage.googleapis.com",
"gemini_edit_modal_key_label": "API Key:", "gemini_edit_modal_title": "Edit Gemini API Key",
"gemini_delete_confirm": "Are you sure you want to delete this Gemini key?", "gemini_edit_modal_key_label": "API Key:",
"excluded_models_label": "Excluded models (optional):", "gemini_delete_confirm": "Are you sure you want to delete this Gemini key?",
"excluded_models_label": "Excluded models (optional):",
"excluded_models_placeholder": "Comma or newline separated, e.g. gemini-1.5-pro, gemini-1.5-flash", "excluded_models_placeholder": "Comma or newline separated, e.g. gemini-1.5-pro, gemini-1.5-flash",
"excluded_models_hint": "Leave empty to allow all models; values are trimmed and deduplicated automatically.", "excluded_models_hint": "Leave empty to allow all models; values are trimmed and deduplicated automatically.",
"excluded_models_count": "Excluding {count} models", "excluded_models_count": "Excluding {{count}} models",
"config_toggle_label": "Enabled", "config_toggle_label": "Enabled",
"config_disabled_badge": "Disabled", "config_disabled_badge": "Disabled",
"codex_title": "Codex API Configuration", "codex_title": "Codex API Configuration",
@@ -244,7 +245,7 @@
"openai_models_search_placeholder": "Filter by name, alias, or description", "openai_models_search_placeholder": "Filter by name, alias, or description",
"openai_models_search_empty": "No models match your search. Try a different keyword.", "openai_models_search_empty": "No models match your search. Try a different keyword.",
"openai_models_fetch_invalid_url": "Please enter a valid Base URL first", "openai_models_fetch_invalid_url": "Please enter a valid Base URL first",
"openai_models_fetch_added": "{count} new models added", "openai_models_fetch_added": "{{count}} new models added",
"openai_edit_modal_title": "Edit OpenAI Compatible Provider", "openai_edit_modal_title": "Edit OpenAI Compatible Provider",
"openai_edit_modal_name_label": "Provider Name:", "openai_edit_modal_name_label": "Provider Name:",
"openai_edit_modal_url_label": "Base URL:", "openai_edit_modal_url_label": "Base URL:",
@@ -278,19 +279,19 @@
"delete_button": "Delete", "delete_button": "Delete",
"delete_confirm": "Are you sure you want to delete file", "delete_confirm": "Are you sure you want to delete file",
"delete_all_confirm": "Are you sure you want to delete all auth files? This operation cannot be undone!", "delete_all_confirm": "Are you sure you want to delete all auth files? This operation cannot be undone!",
"delete_filtered_confirm": "Are you sure you want to delete all {type} auth files? This operation cannot be undone!", "delete_filtered_confirm": "Are you sure you want to delete all {{type}} auth files? This operation cannot be undone!",
"upload_error_json": "Only JSON files are allowed", "upload_error_json": "Only JSON files are allowed",
"upload_success": "File uploaded successfully", "upload_success": "File uploaded successfully",
"download_success": "File downloaded successfully", "download_success": "File downloaded successfully",
"delete_success": "File deleted successfully", "delete_success": "File deleted successfully",
"delete_all_success": "Successfully deleted", "delete_all_success": "Successfully deleted",
"delete_filtered_success": "Deleted {count} {type} auth files successfully", "delete_filtered_success": "Deleted {{count}} {{type}} auth files successfully",
"delete_filtered_partial": "{type} auth files deletion finished: {success} succeeded, {failed} failed", "delete_filtered_partial": "{{type}} auth files deletion finished: {{success}} succeeded, {{failed}} failed",
"delete_filtered_none": "No deletable auth files under the current filter ({type})", "delete_filtered_none": "No deletable auth files under the current filter ({{type}})",
"files_count": "files", "files_count": "files",
"pagination_prev": "Previous", "pagination_prev": "Previous",
"pagination_next": "Next", "pagination_next": "Next",
"pagination_info": "Page {current} / {total} · {count} files", "pagination_info": "Page {{current}} / {{total}} · {{count}} files",
"search_label": "Search configs", "search_label": "Search configs",
"search_placeholder": "Filter by name, type, or provider", "search_placeholder": "Filter by name, type, or provider",
"page_size_label": "Per page", "page_size_label": "Per page",
@@ -313,12 +314,22 @@
"type_aistudio": "AIStudio", "type_aistudio": "AIStudio",
"type_claude": "Claude", "type_claude": "Claude",
"type_codex": "Codex", "type_codex": "Codex",
"type_antigravity": "Antigravity", "type_antigravity": "Antigravity",
"type_iflow": "iFlow", "type_iflow": "iFlow",
"type_vertex": "Vertex", "type_vertex": "Vertex",
"type_empty": "Empty", "type_empty": "Empty",
"type_unknown": "Other" "type_unknown": "Other",
}, "type_virtual": "Virtual auth file",
"models_button": "Models",
"models_title": "Supported models",
"models_loading": "Loading model list...",
"models_empty": "No available models for this credential",
"models_empty_desc": "This credential may not be loaded by the server yet, or no models are bound to it.",
"models_unsupported": "This feature is not supported in the current version",
"models_unsupported_desc": "Please update CLI Proxy API to the latest version and try again",
"models_excluded_badge": "Excluded",
"models_excluded_hint": "This model is excluded by OAuth"
},
"vertex_import": { "vertex_import": {
"title": "Vertex AI Credential Import", "title": "Vertex AI Credential Import",
"description": "Upload a Google service account JSON to store it as auth-dir/vertex-<project>.json using the same rules as the CLI vertex-import helper.", "description": "Upload a Google service account JSON to store it as auth-dir/vertex-<project>.json using the same rules as the CLI vertex-import helper.",
@@ -343,7 +354,7 @@
"description": "Per-provider exclusions are shown as cards; click edit to adjust. Wildcards * are supported and the scope follows the auth file filter.", "description": "Per-provider exclusions are shown as cards; click edit to adjust. Wildcards * are supported and the scope follows the auth file filter.",
"add": "Add Exclusion", "add": "Add Exclusion",
"add_title": "Add provider exclusion", "add_title": "Add provider exclusion",
"edit_title": "Edit exclusions for {provider}", "edit_title": "Edit exclusions for {{provider}}",
"refresh": "Refresh", "refresh": "Refresh",
"refreshing": "Refreshing...", "refreshing": "Refreshing...",
"provider_label": "Provider", "provider_label": "Provider",
@@ -358,19 +369,19 @@
"save_success": "Excluded models updated", "save_success": "Excluded models updated",
"save_failed": "Failed to update excluded models", "save_failed": "Failed to update excluded models",
"delete": "Delete Provider", "delete": "Delete Provider",
"delete_confirm": "Delete the exclusion list for {provider}?", "delete_confirm": "Delete the exclusion list for {{provider}}?",
"delete_success": "Exclusion list removed", "delete_success": "Exclusion list removed",
"delete_failed": "Failed to delete exclusion list", "delete_failed": "Failed to delete exclusion list",
"deleting": "Deleting...", "deleting": "Deleting...",
"no_models": "No excluded models", "no_models": "No excluded models",
"model_count": "{count} models excluded", "model_count": "{{count}} models excluded",
"list_empty_all": "No exclusions yet—use “Add Exclusion” to create one.", "list_empty_all": "No exclusions yet—use “Add Exclusion” to create one.",
"list_empty_filtered": "No exclusions in this scope; click “Add Exclusion” to add.", "list_empty_filtered": "No exclusions in this scope; click “Add Exclusion” to add.",
"disconnected": "Connect to the server to view exclusions", "disconnected": "Connect to the server to view exclusions",
"load_failed": "Failed to load exclusion list", "load_failed": "Failed to load exclusion list",
"provider_required": "Please enter a provider first", "provider_required": "Please enter a provider first",
"scope_all": "Scope: All providers", "scope_all": "Scope: All providers",
"scope_provider": "Scope: {provider}", "scope_provider": "Scope: {{provider}}",
"upgrade_required": "This feature requires a newer CLI Proxy API (CPA) version. Please upgrade.", "upgrade_required": "This feature requires a newer CLI Proxy API (CPA) version. Please upgrade.",
"upgrade_required_title": "Please upgrade CLI Proxy API", "upgrade_required_title": "Please upgrade CLI Proxy API",
"upgrade_required_desc": "The current server does not support the OAuth excluded models API. Please upgrade to the latest CLI Proxy API (CPA) version." "upgrade_required_desc": "The current server does not support the OAuth excluded models API. Please upgrade to the latest CLI Proxy API (CPA) version."
@@ -604,7 +615,7 @@
"models_loading": "Loading available models...", "models_loading": "Loading available models...",
"models_empty": "No models returned by /v1/models", "models_empty": "No models returned by /v1/models",
"models_error": "Failed to load model list", "models_error": "Failed to load model list",
"models_count": "{count} available models", "models_count": "{{count}} available models",
"version_check_title": "Update Check", "version_check_title": "Update Check",
"version_check_desc": "Call the /latest-version endpoint to compare with the server version and see if an update is available.", "version_check_desc": "Call the /latest-version endpoint to compare with the server version and see if an update is available.",
"version_current_label": "Current version", "version_current_label": "Current version",
@@ -612,7 +623,7 @@
"version_check_button": "Check for updates", "version_check_button": "Check for updates",
"version_check_idle": "Click to check for updates", "version_check_idle": "Click to check for updates",
"version_checking": "Checking for the latest version...", "version_checking": "Checking for the latest version...",
"version_update_available": "An update is available: {version}", "version_update_available": "An update is available: {{version}}",
"version_is_latest": "You are on the latest version", "version_is_latest": "You are on the latest version",
"version_check_error": "Update check failed", "version_check_error": "Update check failed",
"version_current_missing": "Server version is unavailable; cannot compare", "version_current_missing": "Server version is unavailable; cannot compare",
@@ -637,7 +648,7 @@
"gemini_key_deleted": "Gemini key deleted successfully", "gemini_key_deleted": "Gemini key deleted successfully",
"gemini_multi_input_required": "Please enter at least one Gemini key", "gemini_multi_input_required": "Please enter at least one Gemini key",
"gemini_multi_failed": "Gemini bulk add failed", "gemini_multi_failed": "Gemini bulk add failed",
"gemini_multi_summary": "Gemini bulk add finished: {success} added, {skipped} skipped, {failed} failed", "gemini_multi_summary": "Gemini bulk add finished: {{success}} added, {{skipped}} skipped, {{failed}} failed",
"codex_config_added": "Codex configuration added successfully", "codex_config_added": "Codex configuration added successfully",
"codex_config_updated": "Codex configuration updated successfully", "codex_config_updated": "Codex configuration updated successfully",
"codex_config_deleted": "Codex configuration deleted successfully", "codex_config_deleted": "Codex configuration deleted successfully",

View File

@@ -137,14 +137,15 @@
"gemini_item_title": "Gemini密钥", "gemini_item_title": "Gemini密钥",
"gemini_add_modal_title": "添加Gemini API密钥", "gemini_add_modal_title": "添加Gemini API密钥",
"gemini_add_modal_key_label": "API密钥", "gemini_add_modal_key_label": "API密钥",
"gemini_add_modal_key_placeholder": "输入 Gemini API 密钥", "gemini_add_modal_key_placeholder": "输入 Gemini API 密钥",
"gemini_add_modal_key_hint": "逐条输入密钥,可同时指定可选 Base URL。", "gemini_add_modal_key_hint": "逐条输入密钥,可同时指定可选 Base URL。",
"gemini_keys_add_btn": "添加密钥", "gemini_keys_add_btn": "添加密钥",
"gemini_base_url_placeholder": "可选 Base URL,如 https://generativelanguage.googleapis.com", "gemini_base_url_label": "Base URL (可选)",
"gemini_edit_modal_title": "编辑Gemini API密钥", "gemini_base_url_placeholder": "例如: https://generativelanguage.googleapis.com",
"gemini_edit_modal_key_label": "API密钥:", "gemini_edit_modal_title": "编辑Gemini API密钥",
"gemini_delete_confirm": "确定要删除这个Gemini密钥吗", "gemini_edit_modal_key_label": "API密钥:",
"excluded_models_label": "排除的模型 (可选):", "gemini_delete_confirm": "确定要删除这个Gemini密钥吗",
"excluded_models_label": "排除的模型 (可选):",
"excluded_models_placeholder": "用逗号或换行分隔,例如: gemini-1.5-pro, gemini-1.5-flash", "excluded_models_placeholder": "用逗号或换行分隔,例如: gemini-1.5-pro, gemini-1.5-flash",
"excluded_models_hint": "留空表示不过滤;保存时会自动去重并忽略空白。", "excluded_models_hint": "留空表示不过滤;保存时会自动去重并忽略空白。",
"excluded_models_count": "排除 {{count}} 个模型", "excluded_models_count": "排除 {{count}} 个模型",

View File

@@ -1676,12 +1676,12 @@ export function AiProvidersPage() {
value={geminiForm.apiKey} value={geminiForm.apiKey}
onChange={(e) => setGeminiForm((prev) => ({ ...prev, apiKey: e.target.value }))} onChange={(e) => setGeminiForm((prev) => ({ ...prev, apiKey: e.target.value }))}
/> />
<Input <Input
label={t('ai_providers.gemini_base_url_placeholder')} label={t('ai_providers.gemini_base_url_label')}
placeholder={t('ai_providers.gemini_base_url_placeholder')} placeholder={t('ai_providers.gemini_base_url_placeholder')}
value={geminiForm.baseUrl ?? ''} value={geminiForm.baseUrl ?? ''}
onChange={(e) => setGeminiForm((prev) => ({ ...prev, baseUrl: e.target.value }))} onChange={(e) => setGeminiForm((prev) => ({ ...prev, baseUrl: e.target.value }))}
/> />
<HeaderInputList <HeaderInputList
entries={headersToEntries(geminiForm.headers as any)} entries={headersToEntries(geminiForm.headers as any)}
onChange={(entries) => setGeminiForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))} onChange={(entries) => setGeminiForm((prev) => ({ ...prev, headers: buildHeaderObject(entries) }))}

View File

@@ -31,7 +31,7 @@
} }
.pageTitle { .pageTitle {
font-size: 22px; font-size: 28px;
font-weight: 700; font-weight: 700;
color: var(--text-primary); color: var(--text-primary);
margin: 0; margin: 0;