feat(webui): optimize frontend terminology and i18n keys

This commit is contained in:
Wha1eChai
2026-01-09 19:55:34 +08:00
parent 07a9586aee
commit 8e221e3fc7
6 changed files with 65 additions and 61 deletions

View File

@@ -165,11 +165,9 @@ document.addEventListener('alpine:init', () => {
clearInterval(pollInterval); clearInterval(pollInterval);
Alpine.store('global').oauthProgress.active = false; Alpine.store('global').oauthProgress.active = false;
const actionKey = reAuthEmail ? 'reauthenticated' : 'added'; const actionKey = reAuthEmail ? 'accountReauthSuccess' : 'accountAddedSuccess';
const action = Alpine.store('global').t(actionKey);
const successfully = Alpine.store('global').t('successfully');
Alpine.store('global').showToast( Alpine.store('global').showToast(
`${Alpine.store('global').t('accounts')} ${action} ${successfully}`, Alpine.store('global').t(actionKey),
'success' 'success'
); );
document.getElementById('add_account_modal')?.close(); document.getElementById('add_account_modal')?.close();

View File

@@ -257,7 +257,7 @@
<!-- Add Account Modal --> <!-- Add Account Modal -->
<dialog id="add_account_modal" class="modal backdrop-blur-sm"> <dialog id="add_account_modal" class="modal backdrop-blur-sm">
<div class="modal-box bg-space-900 border border-space-border text-gray-300 shadow-[0_0_50px_rgba(0,0,0,0.5)]"> <div class="modal-box bg-space-900 border border-space-border text-gray-300 shadow-[0_0_50px_rgba(0,0,0,0.5)]">
<h3 class="font-bold text-lg text-white" x-text="$store.global.t('addNode')">Add New Account</h3> <h3 class="font-bold text-lg text-white" x-text="$store.global.t('addAccount')">Add New Account</h3>
<div class="py-6 flex flex-col gap-4"> <div class="py-6 flex flex-col gap-4">
<p class="text-sm text-gray-400" x-text="$store.global.t('connectGoogleDesc')">Connect a Google <p class="text-sm text-gray-400" x-text="$store.global.t('connectGoogleDesc')">Connect a Google

View File

@@ -36,7 +36,7 @@ document.addEventListener('alpine:init', () => {
systemConfig: "System Configuration", systemConfig: "System Configuration",
language: "Language", language: "Language",
pollingInterval: "Polling Interval", pollingInterval: "Polling Interval",
logBufferSize: "Log Buffer Size", maxDisplayLogs: "Max Displayed Logs",
showExhausted: "Show Exhausted Models", showExhausted: "Show Exhausted Models",
showExhaustedDesc: "Display models even if they have 0% remaining quota.", showExhaustedDesc: "Display models even if they have 0% remaining quota.",
compactMode: "Compact Mode", compactMode: "Compact Mode",
@@ -44,13 +44,13 @@ document.addEventListener('alpine:init', () => {
saveChanges: "Save Changes", saveChanges: "Save Changes",
autoScroll: "Auto-scroll", autoScroll: "Auto-scroll",
clearLogs: "Clear Logs", clearLogs: "Clear Logs",
accessCredentials: "Access Credentials", accountManagement: "Account Management",
manageTokens: "Manage OAuth tokens and session states", manageTokens: "Manage Google Account tokens and authorization states",
addNode: "Add Node", addAccount: "Add Account",
status: "STATUS", status: "STATUS",
enabled: "ENABLED", enabled: "ENABLED",
health: "HEALTH", health: "STATUS",
identity: "IDENTITY (EMAIL)", accountEmail: "ACCOUNT (EMAIL)",
source: "SOURCE", source: "SOURCE",
projectId: "PROJECT ID", projectId: "PROJECT ID",
sessionState: "SESSION STATE", sessionState: "SESSION STATE",
@@ -62,6 +62,8 @@ document.addEventListener('alpine:init', () => {
reauthenticated: "re-authenticated", reauthenticated: "re-authenticated",
added: "added", added: "added",
successfully: "successfully", successfully: "successfully",
accountAddedSuccess: "Account added successfully",
accountReauthSuccess: "Account re-authenticated successfully",
failedToGetAuthUrl: "Failed to get auth URL", failedToGetAuthUrl: "Failed to get auth URL",
failedToStartOAuth: "Failed to start OAuth flow", failedToStartOAuth: "Failed to start OAuth flow",
oauthInProgress: "OAuth in progress. Please complete authentication in the popup window...", oauthInProgress: "OAuth in progress. Please complete authentication in the popup window...",
@@ -72,13 +74,13 @@ document.addEventListener('alpine:init', () => {
tabInterface: "Interface", tabInterface: "Interface",
tabClaude: "Claude CLI", tabClaude: "Claude CLI",
tabModels: "Models", tabModels: "Models",
tabServer: "Server Info", tabServer: "Server Settings",
// Dashboard // Dashboard
registeredNodes: "Registered Nodes", linkedAccounts: "Linked Accounts",
noSignal: "NO SIGNAL DETECTED", noSignal: "NO SIGNAL DETECTED",
establishingUplink: "ESTABLISHING UPLINK...", establishingUplink: "ESTABLISHING UPLINK...",
// Settings - Models // Settings - Models
modelsDesc: "Configure model visibility, pinning, and request redirection.", modelsDesc: "Configure model visibility, pinning, and request routing.",
modelsPageDesc: "Real-time quota and status for all available models.", modelsPageDesc: "Real-time quota and status for all available models.",
showHidden: "Show Hidden Models", showHidden: "Show Hidden Models",
modelId: "Model ID", modelId: "Model ID",
@@ -86,24 +88,24 @@ document.addEventListener('alpine:init', () => {
pinToTop: "Pin to top", pinToTop: "Pin to top",
toggleVisibility: "Toggle Visibility", toggleVisibility: "Toggle Visibility",
noModels: "NO MODELS DETECTED", noModels: "NO MODELS DETECTED",
modelMappingHint: "Server-side model redirection. Claude Code users: see 'Claude CLI' tab for easier setup.", modelMappingHint: "Server-side model routing. Claude Code users: see 'Claude CLI' tab for client-side setup.",
modelMapping: "Mapping (Target Model)", modelMapping: "Mapping (Target Model ID)",
// Settings - Claude // Settings - Claude
proxyConnection: "Proxy Connection", proxyConnection: "Proxy Connection",
modelSelection: "Model Selection", modelSelection: "Model Selection",
aliasOverrides: "ALIAS OVERRIDES", defaultModelAliases: "DEFAULT MODEL ALIASES",
opusAlias: "Opus Alias", opusAlias: "Opus Alias",
sonnetAlias: "Sonnet Alias", sonnetAlias: "Sonnet Alias",
haikuAlias: "Haiku Alias", haikuAlias: "Haiku Alias",
claudeSettingsAlert: "Settings below directly modify ~/.claude/settings.json. Restart Claude CLI to apply.", claudeSettingsAlert: "Settings below directly modify ~/.claude/settings.json. Restart Claude CLI to apply.",
writeToConfig: "Write to Config", applyToClaude: "Apply to Claude CLI",
// Settings - Server // Settings - Server
port: "Port", port: "Port",
uiVersion: "UI Version", uiVersion: "UI Version",
debugMode: "Debug Mode", debugMode: "Debug Mode",
environment: "Environment", environment: "Environment",
serverReadOnly: "Server settings are read-only. Modify config.json or .env and restart the server to change.", serverReadOnly: "Settings managed via config.json. Restart server to apply changes.",
dangerZone: "Danger Zone / Advanced", advancedSettings: "Advanced Settings",
reloadConfigTitle: "Reload Account Config", reloadConfigTitle: "Reload Account Config",
reloadConfigDesc: "Force reload accounts.json from disk", reloadConfigDesc: "Force reload accounts.json from disk",
reload: "Reload", reload: "Reload",
@@ -185,8 +187,8 @@ document.addEventListener('alpine:init', () => {
totalColon: "Total:", totalColon: "Total:",
todayColon: "Today:", todayColon: "Today:",
hour1Colon: "1H:", hour1Colon: "1H:",
smart: "Smart", frequentModels: "Frequent",
smartTitle: "Select Top 5 most used models (24h)", smartTitle: "Auto-select top 5 most used models (24h)",
activeCount: "{count} Active", activeCount: "{count} Active",
allCaps: "ALL", allCaps: "ALL",
claudeCaps: "CLAUDE", claudeCaps: "CLAUDE",
@@ -200,14 +202,14 @@ document.addEventListener('alpine:init', () => {
maxRetries: "Max Retries", maxRetries: "Max Retries",
retryBaseDelay: "Retry Base Delay (ms)", retryBaseDelay: "Retry Base Delay (ms)",
retryMaxDelay: "Retry Max Delay (ms)", retryMaxDelay: "Retry Max Delay (ms)",
persistTokenCache: "Persist Token Cache", persistentSessions: "Persistent Sessions",
persistTokenDesc: "Save OAuth tokens to disk for faster restarts", persistTokenDesc: "Save OAuth sessions to disk for faster restarts",
rateLimiting: "Account Rate Limiting & Timeouts", rateLimiting: "Account Rate Limiting & Timeouts",
defaultCooldown: "Default Cooldown Time", defaultCooldown: "Default Cooldown Time",
maxWaitThreshold: "Max Wait Threshold (Sticky)", maxWaitThreshold: "Max Wait Threshold (Sticky)",
maxWaitDesc: "Maximum time to wait for a sticky account to reset before failing or switching.", maxWaitDesc: "Maximum time to wait for a sticky account to reset before switching.",
saveConfigServer: "Save Configuration", saveConfigServer: "Save Configuration",
serverRestartAlert: "Some changes may require server restart. Config is saved to {path}", serverRestartAlert: "Changes saved to {path}. Restart server to apply some settings.",
changePassword: "Change WebUI Password", changePassword: "Change WebUI Password",
changePasswordDesc: "Update the password for accessing this dashboard", changePasswordDesc: "Update the password for accessing this dashboard",
currentPassword: "Current Password", currentPassword: "Current Password",
@@ -249,6 +251,7 @@ document.addEventListener('alpine:init', () => {
gemini1mMode: "Gemini 1M Context Mode", gemini1mMode: "Gemini 1M Context Mode",
gemini1mDesc: "Appends [1m] suffix to Gemini models for 1M context window support.", gemini1mDesc: "Appends [1m] suffix to Gemini models for 1M context window support.",
gemini1mWarning: "⚠ Large context may reduce Gemini-3-Pro performance.", gemini1mWarning: "⚠ Large context may reduce Gemini-3-Pro performance.",
clickToSet: "Click to configure...",
}, },
zh: { zh: {
dashboard: "仪表盘", dashboard: "仪表盘",
@@ -273,7 +276,7 @@ document.addEventListener('alpine:init', () => {
systemConfig: "系统配置", systemConfig: "系统配置",
language: "语言设置", language: "语言设置",
pollingInterval: "数据轮询间隔", pollingInterval: "数据轮询间隔",
logBufferSize: "日志缓冲大小", maxDisplayLogs: "最大日志显示行数",
showExhausted: "显示耗尽模型", showExhausted: "显示耗尽模型",
showExhaustedDesc: "即使配额为 0% 也显示模型。", showExhaustedDesc: "即使配额为 0% 也显示模型。",
compactMode: "紧凑模式", compactMode: "紧凑模式",
@@ -281,13 +284,13 @@ document.addEventListener('alpine:init', () => {
saveChanges: "保存更改", saveChanges: "保存更改",
autoScroll: "自动滚动", autoScroll: "自动滚动",
clearLogs: "清除日志", clearLogs: "清除日志",
accessCredentials: "访问凭证", accountManagement: "账号管理",
manageTokens: "管理 OAuth 令牌和会话状态", manageTokens: "管理已授权的 Google 账号及其状态",
addNode: "添加节点", addAccount: "添加账号",
status: "状态", status: "状态",
enabled: "启用", enabled: "启用",
health: "健康度", health: "状态",
identity: "身份 (邮箱)", accountEmail: "账号 (邮箱)",
source: "来源", source: "来源",
projectId: "项目 ID", projectId: "项目 ID",
sessionState: "会话状态", sessionState: "会话状态",
@@ -299,6 +302,8 @@ document.addEventListener('alpine:init', () => {
reauthenticated: "已重新认证", reauthenticated: "已重新认证",
added: "已添加", added: "已添加",
successfully: "成功", successfully: "成功",
accountAddedSuccess: "账号添加成功",
accountReauthSuccess: "账号重新认证成功",
failedToGetAuthUrl: "获取认证链接失败", failedToGetAuthUrl: "获取认证链接失败",
failedToStartOAuth: "启动 OAuth 流程失败", failedToStartOAuth: "启动 OAuth 流程失败",
oauthInProgress: "OAuth 授权进行中,请在弹出窗口中完成认证...", oauthInProgress: "OAuth 授权进行中,请在弹出窗口中完成认证...",
@@ -310,13 +315,13 @@ document.addEventListener('alpine:init', () => {
tabInterface: "界面设置", tabInterface: "界面设置",
tabClaude: "Claude CLI", tabClaude: "Claude CLI",
tabModels: "模型管理", tabModels: "模型管理",
tabServer: "服务器信息", tabServer: "服务器设置",
// Dashboard // Dashboard
registeredNodes: "已注册节点", linkedAccounts: "已关联账号",
noSignal: "无信号连接", noSignal: "无信号连接",
establishingUplink: "正在建立上行链路...", establishingUplink: "正在建立上行链路...",
// Settings - Models // Settings - Models
modelsDesc: "配置模型的可见性、置顶和请求重定向。", modelsDesc: "配置模型的可见性、置顶和请求路由。",
modelsPageDesc: "所有可用模型的实时配额和状态。", modelsPageDesc: "所有可用模型的实时配额和状态。",
showHidden: "显示隐藏模型", showHidden: "显示隐藏模型",
modelId: "模型 ID", modelId: "模型 ID",
@@ -324,24 +329,24 @@ document.addEventListener('alpine:init', () => {
pinToTop: "置顶", pinToTop: "置顶",
toggleVisibility: "切换可见性", toggleVisibility: "切换可见性",
noModels: "未检测到模型", noModels: "未检测到模型",
modelMappingHint: "服务端模型重定向功能。Claude Code 用户请使用 'Claude CLI' 标签页以便捷配置。", modelMappingHint: "服务端模型路由功能。Claude Code 用户请使用 'Claude CLI' 标签页以便捷配置。",
modelMapping: "映射 (目标模型)", modelMapping: "映射 (目标模型 ID)",
// Settings - Claude // Settings - Claude
proxyConnection: "代理连接", proxyConnection: "代理连接",
modelSelection: "模型选择", modelSelection: "模型选择",
aliasOverrides: "别名覆盖", defaultModelAliases: "默认模型映射 (别名)",
opusAlias: "Opus 别名", opusAlias: "Opus 别名",
sonnetAlias: "Sonnet 别名", sonnetAlias: "Sonnet 别名",
haikuAlias: "Haiku 别名", haikuAlias: "Haiku 别名",
claudeSettingsAlert: "以下设置直接修改 ~/.claude/settings.json。重启 Claude CLI 生效。", claudeSettingsAlert: "以下设置直接修改 ~/.claude/settings.json。重启 Claude CLI 生效。",
writeToConfig: "写入配置", applyToClaude: "应用到 Claude CLI",
// Settings - Server // Settings - Server
port: "端口", port: "端口",
uiVersion: "UI 版本", uiVersion: "UI 版本",
debugMode: "调试模式", debugMode: "调试模式",
environment: "运行环境", environment: "运行环境",
serverReadOnly: "服务器设置只读。修改 config.json 或 .env 并重启服务器以生效。", serverReadOnly: "配置由 config.json 管理。重启服务器以应用更改。",
dangerZone: "危险区域 / 高级", advancedSettings: "高级设置",
reloadConfigTitle: "重载账号配置", reloadConfigTitle: "重载账号配置",
reloadConfigDesc: "强制从磁盘重新读取 accounts.json", reloadConfigDesc: "强制从磁盘重新读取 accounts.json",
reload: "重载", reload: "重载",
@@ -423,8 +428,8 @@ document.addEventListener('alpine:init', () => {
totalColon: "总计:", totalColon: "总计:",
todayColon: "今日:", todayColon: "今日:",
hour1Colon: "1小时:", hour1Colon: "1小时:",
smart: "智能选择", frequentModels: "常用推荐",
smartTitle: "自动选过去 24 小时最常用的 5 个模型", smartTitle: "自动选过去 24 小时最常用的 5 个模型",
activeCount: "{count} 活跃", activeCount: "{count} 活跃",
allCaps: "全部", allCaps: "全部",
claudeCaps: "CLAUDE", claudeCaps: "CLAUDE",
@@ -438,14 +443,14 @@ document.addEventListener('alpine:init', () => {
maxRetries: "最大重试次数", maxRetries: "最大重试次数",
retryBaseDelay: "重试基础延迟 (毫秒)", retryBaseDelay: "重试基础延迟 (毫秒)",
retryMaxDelay: "重试最大延迟 (毫秒)", retryMaxDelay: "重试最大延迟 (毫秒)",
persistTokenCache: "持久化令牌缓存", persistentSessions: "持久化登录会话",
persistTokenDesc: "将 OAuth 令牌保存到磁盘以实现快速重启", persistTokenDesc: "将登录会话保存到磁盘以实现快速重启",
rateLimiting: "账号限流与超时", rateLimiting: "账号限流与超时",
defaultCooldown: "默认冷却时间", defaultCooldown: "默认冷却时间",
maxWaitThreshold: "最大等待阈值 (粘性会话)", maxWaitThreshold: "最大等待阈值 (粘性会话)",
maxWaitDesc: "粘性账号在失败或切换前等待重置的最长时间。", maxWaitDesc: "粘性账号在失败或切换前等待重置的最长时间。",
saveConfigServer: "保存配置", saveConfigServer: "保存配置",
serverRestartAlert: "部分更改可能需要重启服务器。配置已保存至 {path}", serverRestartAlert: "配置已保存至 {path}。部分更改可能需要重启服务器。",
changePassword: "修改 WebUI 密码", changePassword: "修改 WebUI 密码",
changePasswordDesc: "更新访问此仪表盘的密码", changePasswordDesc: "更新访问此仪表盘的密码",
currentPassword: "当前密码", currentPassword: "当前密码",
@@ -466,7 +471,7 @@ document.addEventListener('alpine:init', () => {
// 账号页面 // 账号页面
searchAccounts: "搜索账号...", searchAccounts: "搜索账号...",
noAccountsYet: "还没有添加任何账号", noAccountsYet: "还没有添加任何账号",
noAccountsDesc: "点击上方的 \"添加节点\" 按钮通过 OAuth 添加 Google 账号,或者使用 CLI 命令导入凭证。", noAccountsDesc: "点击上方的 \"添加账号\" 按钮通过 OAuth 添加 Google 账号,或者使用 CLI 命令导入凭证。",
addFirstAccount: "添加第一个账号", addFirstAccount: "添加第一个账号",
noSearchResults: "没有找到匹配的账号", noSearchResults: "没有找到匹配的账号",
clearSearch: "清除搜索", clearSearch: "清除搜索",
@@ -487,6 +492,7 @@ document.addEventListener('alpine:init', () => {
gemini1mMode: "Gemini 1M 上下文模式", gemini1mMode: "Gemini 1M 上下文模式",
gemini1mDesc: "为 Gemini 模型添加 [1m] 后缀以支持 1M 上下文窗口。", gemini1mDesc: "为 Gemini 模型添加 [1m] 后缀以支持 1M 上下文窗口。",
gemini1mWarning: "⚠ 大上下文可能降低 Gemini-3-Pro 性能。", gemini1mWarning: "⚠ 大上下文可能降低 Gemini-3-Pro 性能。",
clickToSet: "点击进行配置...",
} }
}, },

View File

@@ -3,12 +3,12 @@
<div class="flex items-center justify-between gap-4 mb-6"> <div class="flex items-center justify-between gap-4 mb-6">
<!-- Title with inline subtitle --> <!-- Title with inline subtitle -->
<div class="flex items-baseline gap-3"> <div class="flex items-baseline gap-3">
<h1 class="text-2xl font-bold text-white tracking-tight" x-text="$store.global.t('accessCredentials')"> <h1 class="text-2xl font-bold text-white tracking-tight" x-text="$store.global.t('accountManagement')">
Access Credentials Account Management
</h1> </h1>
<span class="text-[10px] font-mono text-gray-600 uppercase tracking-[0.15em]" <span class="text-[10px] font-mono text-gray-600 uppercase tracking-[0.15em]"
x-text="$store.global.t('manageTokens')"> x-text="$store.global.t('manageTokens')">
Manage OAuth tokens and session states Manage Google Account tokens and authorization states
</span> </span>
</div> </div>
@@ -37,7 +37,7 @@
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg> </svg>
<span x-text="$store.global.t('addNode')">Add Node</span> <span x-text="$store.global.t('addAccount')">Add Account</span>
</button> </button>
</div> </div>
</div> </div>
@@ -48,7 +48,7 @@
<thead x-show="$store.data.accounts.length > 0"> <thead x-show="$store.data.accounts.length > 0">
<tr class="bg-space-900/50 border-b border-space-border/50"> <tr class="bg-space-900/50 border-b border-space-border/50">
<th class="pl-6 py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-16" x-text="$store.global.t('enabled')">Enabled</th> <th class="pl-6 py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-16" x-text="$store.global.t('enabled')">Enabled</th>
<th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider flex-1 min-w-[200px]" x-text="$store.global.t('identity')">Identity (Email)</th> <th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider flex-1 min-w-[200px]" x-text="$store.global.t('accountEmail')">Account (Email)</th>
<th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-20" x-text="$store.global.t('source')">Source</th> <th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-20" x-text="$store.global.t('source')">Source</th>
<th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-24" x-text="$store.global.t('health')">Health</th> <th class="py-3 text-left text-[10px] font-bold text-gray-500 uppercase tracking-wider w-24" x-text="$store.global.t('health')">Health</th>
<th class="py-3 pr-6 text-right text-[10px] font-bold text-gray-500 uppercase tracking-wider w-32" x-text="$store.global.t('operations')">Operations</th> <th class="py-3 pr-6 text-right text-[10px] font-bold text-gray-500 uppercase tracking-wider w-32" x-text="$store.global.t('operations')">Operations</th>

View File

@@ -45,7 +45,7 @@
<div class="stat-title text-gray-500 font-mono text-xs uppercase tracking-wider truncate" <div class="stat-title text-gray-500 font-mono text-xs uppercase tracking-wider truncate"
x-text="$store.global.t('totalAccounts')"></div> x-text="$store.global.t('totalAccounts')"></div>
<div class="stat-desc text-cyan-400/60 text-[10px] truncate flex items-center gap-1"> <div class="stat-desc text-cyan-400/60 text-[10px] truncate flex items-center gap-1">
<span x-text="$store.global.t('registeredNodes')"></span> <span x-text="$store.global.t('linkedAccounts')"></span>
<svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg class="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg> </svg>
@@ -219,7 +219,7 @@
x-text="displayMode === 'family' ? $store.global.t('selectFamilies') : $store.global.t('selectModels')"></span> x-text="displayMode === 'family' ? $store.global.t('selectFamilies') : $store.global.t('selectModels')"></span>
<div class="flex gap-1"> <div class="flex gap-1">
<button @click="autoSelectTopN(5)" class="text-[10px] text-neon-purple hover:underline" <button @click="autoSelectTopN(5)" class="text-[10px] text-neon-purple hover:underline"
:title="$store.global.t('smartTitle')" x-text="$store.global.t('smart')"> :title="$store.global.t('smartTitle')" x-text="$store.global.t('frequentModels')">
Smart Smart
</button> </button>
<span class="text-gray-600">|</span> <span class="text-gray-600">|</span>

View File

@@ -114,7 +114,7 @@
<!-- Log Buffer --> <!-- Log Buffer -->
<div class="form-control col-span-full"> <div class="form-control col-span-full">
<label class="label"> <label class="label">
<span class="label-text text-gray-300" x-text="$store.global.t('logBufferSize')">Log Buffer <span class="label-text text-gray-300" x-text="$store.global.t('maxDisplayLogs')">Log Buffer
Size</span> Size</span>
<span class="label-text-alt font-mono text-neon-purple" <span class="label-text-alt font-mono text-neon-purple"
x-text="$store.settings.logLimit + ' ' + $store.global.t('lines')"></span> x-text="$store.settings.logLimit + ' ' + $store.global.t('lines')"></span>
@@ -303,7 +303,7 @@
</div> </div>
<div class="divider text-xs font-mono text-gray-600 my-2" <div class="divider text-xs font-mono text-gray-600 my-2"
x-text="$store.global.t('aliasOverrides')">ALIAS OVERRIDES</div> x-text="$store.global.t('defaultModelAliases')">DEFAULT MODEL ALIASES</div>
<!-- Overrides --> <!-- Overrides -->
<div class="space-y-4"> <div class="space-y-4">
@@ -460,7 +460,7 @@
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4" /> d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4" />
</svg> </svg>
<span x-show="!loading" x-text="$store.global.t('writeToConfig')">Write to Config</span> <span x-show="!loading" x-text="$store.global.t('applyToClaude')">Apply to Claude CLI</span>
<span x-show="loading" class="loading loading-spinner loading-xs"></span> <span x-show="loading" class="loading loading-spinner loading-xs"></span>
</button> </button>
</div> </div>
@@ -524,7 +524,7 @@
<div x-show="!isEditing(modelId)" <div x-show="!isEditing(modelId)"
class="flex items-center gap-2 group-hover:text-white transition-colors cursor-pointer py-2" class="flex items-center gap-2 group-hover:text-white transition-colors cursor-pointer py-2"
@click="startEditing(modelId); newMapping = config.mapping || ''; $nextTick(() => $refs['input-' + modelId]?.focus())"> @click="startEditing(modelId); newMapping = config.mapping || ''; $nextTick(() => $refs['input-' + modelId]?.focus())">
<span x-text="config.mapping || 'Click to set...'" <span x-text="config.mapping || $store.global.t('clickToSet')"
:class="{'text-gray-600 italic': !config.mapping, 'text-gray-300': config.mapping}" :class="{'text-gray-600 italic': !config.mapping, 'text-gray-300': config.mapping}"
class="text-xs font-mono"></span> class="text-xs font-mono"></span>
<svg class="w-3 h-3 text-gray-600 opacity-0 group-hover:opacity-100 transition-opacity" <svg class="w-3 h-3 text-gray-600 opacity-0 group-hover:opacity-100 transition-opacity"
@@ -698,7 +698,7 @@
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<span class="text-sm font-medium text-gray-200" <span class="text-sm font-medium text-gray-200"
:class="serverConfig.persistTokenCache ? 'text-neon-green' : ''" :class="serverConfig.persistTokenCache ? 'text-neon-green' : ''"
x-text="$store.global.t('persistTokenCache')">Persist Token Cache</span> x-text="$store.global.t('persistentSessions')">Persist Token Cache</span>
<span class="text-[11px] text-gray-500" <span class="text-[11px] text-gray-500"
x-text="$store.global.t('persistTokenDesc')">Save OAuth tokens to disk for faster x-text="$store.global.t('persistTokenDesc')">Save OAuth tokens to disk for faster
restarts</span> restarts</span>
@@ -729,9 +729,9 @@
</div> </div>
<div> <div>
<span class="text-sm font-semibold text-gray-200" <span class="text-sm font-semibold text-gray-200"
x-text="$store.global.t('dangerZone')">Advanced Tuning</span> x-text="$store.global.t('advancedSettings')">Advanced Settings</span>
<span class="text-[10px] text-gray-600 block" <span class="text-[10px] text-gray-600 block"
x-text="$store.global.t('serverReadOnly')">Experienced users only</span> x-text="$store.global.t('serverReadOnly')">Settings managed via config.json</span>
</div> </div>
</div> </div>
<svg xmlns="http://www.w3.org/2000/svg" <svg xmlns="http://www.w3.org/2000/svg"