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_add_modal_title": "Add Gemini API Key",
"gemini_add_modal_key_label": "API Keys:",
"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_keys_add_btn": "Add Key",
"gemini_base_url_placeholder": "Optional Base URL, e.g. https://generativelanguage.googleapis.com",
"gemini_edit_modal_title": "Edit Gemini API Key",
"gemini_edit_modal_key_label": "API Key:",
"gemini_delete_confirm": "Are you sure you want to delete this Gemini key?",
"excluded_models_label": "Excluded models (optional):",
"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_keys_add_btn": "Add Key",
"gemini_base_url_label": "Base URL (Optional):",
"gemini_base_url_placeholder": "e.g.: https://generativelanguage.googleapis.com",
"gemini_edit_modal_title": "Edit Gemini API Key",
"gemini_edit_modal_key_label": "API Key:",
"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_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_disabled_badge": "Disabled",
"codex_title": "Codex API Configuration",
@@ -244,7 +245,7 @@
"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_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_name_label": "Provider Name:",
"openai_edit_modal_url_label": "Base URL:",
@@ -278,19 +279,19 @@
"delete_button": "Delete",
"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_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_success": "File uploaded successfully",
"download_success": "File downloaded successfully",
"delete_success": "File deleted successfully",
"delete_all_success": "Successfully deleted",
"delete_filtered_success": "Deleted {count} {type} auth files successfully",
"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_success": "Deleted {{count}} {{type}} auth files successfully",
"delete_filtered_partial": "{{type}} auth files deletion finished: {{success}} succeeded, {{failed}} failed",
"delete_filtered_none": "No deletable auth files under the current filter ({{type}})",
"files_count": "files",
"pagination_prev": "Previous",
"pagination_next": "Next",
"pagination_info": "Page {current} / {total} · {count} files",
"pagination_info": "Page {{current}} / {{total}} · {{count}} files",
"search_label": "Search configs",
"search_placeholder": "Filter by name, type, or provider",
"page_size_label": "Per page",
@@ -313,12 +314,22 @@
"type_aistudio": "AIStudio",
"type_claude": "Claude",
"type_codex": "Codex",
"type_antigravity": "Antigravity",
"type_iflow": "iFlow",
"type_vertex": "Vertex",
"type_empty": "Empty",
"type_unknown": "Other"
},
"type_antigravity": "Antigravity",
"type_iflow": "iFlow",
"type_vertex": "Vertex",
"type_empty": "Empty",
"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": {
"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.",
@@ -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.",
"add": "Add Exclusion",
"add_title": "Add provider exclusion",
"edit_title": "Edit exclusions for {provider}",
"edit_title": "Edit exclusions for {{provider}}",
"refresh": "Refresh",
"refreshing": "Refreshing...",
"provider_label": "Provider",
@@ -358,19 +369,19 @@
"save_success": "Excluded models updated",
"save_failed": "Failed to update excluded models",
"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_failed": "Failed to delete exclusion list",
"deleting": "Deleting...",
"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_filtered": "No exclusions in this scope; click “Add Exclusion” to add.",
"disconnected": "Connect to the server to view exclusions",
"load_failed": "Failed to load exclusion list",
"provider_required": "Please enter a provider first",
"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_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."
@@ -604,7 +615,7 @@
"models_loading": "Loading available models...",
"models_empty": "No models returned by /v1/models",
"models_error": "Failed to load model list",
"models_count": "{count} available models",
"models_count": "{{count}} available models",
"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_current_label": "Current version",
@@ -612,7 +623,7 @@
"version_check_button": "Check for updates",
"version_check_idle": "Click to check for updates",
"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_check_error": "Update check failed",
"version_current_missing": "Server version is unavailable; cannot compare",
@@ -637,7 +648,7 @@
"gemini_key_deleted": "Gemini key deleted successfully",
"gemini_multi_input_required": "Please enter at least one Gemini key",
"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_updated": "Codex configuration updated successfully",
"codex_config_deleted": "Codex configuration deleted successfully",

View File

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

View File

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

View File

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