From 5d14daf486e277dfcb2075864cd56b73a1837f8e Mon Sep 17 00:00:00 2001 From: Sycun <165354365+Sycun@users.noreply.github.com> Date: Sun, 11 Oct 2026 23:58:41 +0800 Subject: [PATCH] style: compact dashboard token usage subtitle --- docs/zh-CN/token-usage-monitoring.md | 2 +- web/static/css/style.css | 2 -- web/static/i18n/en-US.json | 2 +- web/static/i18n/ru-RU.json | 2 +- web/static/i18n/zh-CN.json | 2 +- web/static/js/dashboard.js | 10 ++-------- web/static/js/token-usage-analysis.test.cjs | 3 ++- web/templates/index.html | 7 +++---- 8 files changed, 11 insertions(+), 19 deletions(-) diff --git a/docs/zh-CN/token-usage-monitoring.md b/docs/zh-CN/token-usage-monitoring.md index 98247821..555bd7b8 100644 --- a/docs/zh-CN/token-usage-monitoring.md +++ b/docs/zh-CN/token-usage-monitoring.md @@ -29,7 +29,7 @@ DeepSeek 的未命中输入不等于 Claude 的缓存写入。不能根据文本 ## 功能入口与数据流 -点击首页「Token 用量」卡片进入「系统设置 → Token 用量」,也可直接从设置二级菜单打开。首页卡片显示近 7 天调用次数、今日用量与缓存命中率(缓存读取 Token / 输入 Token)。支持当前项目范围、7/30/90 天切换、八项指标、最多 20 项运行模型排行、每日趋势与完整日明细、最多 20 项最近运行。详情页独立加载,支持手动刷新与请求取消,切换周期不会刷新整个仪表盘;刷新页面可保持该设置分区。 +点击首页「Token 用量」卡片进入「系统设置 → Token 用量」,也可直接从设置二级菜单打开。首页卡片显示近 7 天总用量,副标仅用一行显示今日用量与缓存命中率(缓存读取 Token / 输入 Token),调用次数保留在详情页。支持当前项目范围、7/30/90 天切换、八项指标、最多 20 项运行模型排行、每日趋势与完整日明细、最多 20 项最近运行。详情页独立加载,支持手动刷新与请求取消,切换周期不会刷新整个仪表盘;刷新页面可保持该设置分区。 运行事件 → 流式/非流式用量累加 → `eino_usage_summary` → `process_details` 与 `model_token_usage` → 现有 `/api/usage/tokens`、对话用量接口 → 首页与聊天摘要。 diff --git a/web/static/css/style.css b/web/static/css/style.css index 7b1576ac..3258149f 100644 --- a/web/static/css/style.css +++ b/web/static/css/style.css @@ -47221,8 +47221,6 @@ html[data-theme="dark"] { --tool-blocked-color: #f4bc62; } } /* Provider-reported token analysis, scoped by the dashboard project selector. */ -.dashboard-kpi-sub--tokens { row-gap: 2px; } -#dashboard-kpi-token-cache-text { flex-basis: 100%; } .token-usage-panel { margin-bottom: 20px; padding: 18px 22px; } .token-usage-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; } .token-usage-toolbar { display: flex; align-items: center; gap: 12px; margin-top: 18px; } diff --git a/web/static/i18n/en-US.json b/web/static/i18n/en-US.json index 9f3f913c..4a3ad926 100644 --- a/web/static/i18n/en-US.json +++ b/web/static/i18n/en-US.json @@ -288,7 +288,7 @@ "successRate": "Tool success rate", "tokenUsage": "Token usage", "usageCacheHitRate": "Cache hit {{rate}}", - "tokenUsageSub": "Last {{days}} days: {{calls}} calls · Today {{today}}", + "tokenUsageSub": "Today {{today}} · Cache hit {{rate}}", "noTokenUsageYet": "No usage yet", "clickToViewTasks": "Click to view tasks", "clickToViewChat": "Click to view conversations", diff --git a/web/static/i18n/ru-RU.json b/web/static/i18n/ru-RU.json index 667c550e..d060b292 100644 --- a/web/static/i18n/ru-RU.json +++ b/web/static/i18n/ru-RU.json @@ -288,7 +288,7 @@ "successRate": "Успешность инструментов", "tokenUsage": "Расход токенов", "usageCacheHitRate": "Попадания в кэш {{rate}}", - "tokenUsageSub": "За {{days}} дней {{calls}} вызовов · сегодня {{today}}", + "tokenUsageSub": "Сегодня {{today}} · Кэш {{rate}}", "noTokenUsageYet": "Расхода пока нет", "clickToViewTasks": "Открыть задачи", "clickToViewChat": "Открыть диалоги", diff --git a/web/static/i18n/zh-CN.json b/web/static/i18n/zh-CN.json index a758dbd3..77ed40c6 100644 --- a/web/static/i18n/zh-CN.json +++ b/web/static/i18n/zh-CN.json @@ -288,7 +288,7 @@ "successRate": "工具执行成功率", "tokenUsage": "Token 用量", "usageCacheHitRate": "缓存命中 {{rate}}", - "tokenUsageSub": "近 {{days}} 天 {{calls}} 次调用 · 今日 {{today}}", + "tokenUsageSub": "今日 {{today}} · 缓存命中 {{rate}}", "noTokenUsageYet": "暂无用量", "clickToViewTasks": "点击查看任务管理", "clickToViewChat": "点击查看对话", diff --git a/web/static/js/dashboard.js b/web/static/js/dashboard.js index eec890d3..5ad07c76 100644 --- a/web/static/js/dashboard.js +++ b/web/static/js/dashboard.js @@ -72,7 +72,6 @@ async function refreshDashboard() { setKpiSubText('dashboard-kpi-tools-sub-text', '…'); setKpiSubText('dashboard-kpi-rate-sub-text', '…'); setKpiSubText('dashboard-kpi-token-sub-text', '…'); - setKpiSubText('dashboard-kpi-token-cache-text', '…'); hideEl('dashboard-kpi-vuln-critical-badge'); hideEl('dashboard-alert-banner'); setRecentVulnsLoading(); @@ -443,7 +442,6 @@ async function refreshDashboard() { setEl('dashboard-kpi-tools-calls', '-'); setEl('dashboard-kpi-token-usage', '-'); setKpiSubText('dashboard-kpi-token-sub-text', '-'); - setKpiSubText('dashboard-kpi-token-cache-text', '-'); setKpiSubText('dashboard-kpi-tasks-sub-text', '-'); setKpiSubText('dashboard-kpi-vuln-sub-text', '-'); setKpiSubText('dashboard-kpi-tools-sub-text', '-'); @@ -715,13 +713,10 @@ function renderDashboardTokenUsage(res) { if (!summary) { setEl('dashboard-kpi-token-usage', '-'); setKpiSubText('dashboard-kpi-token-sub-text', '-'); - setKpiSubText('dashboard-kpi-token-cache-text', '-'); return; } const cacheRate = tokenUsageCacheRate(summary); - setKpiSubText('dashboard-kpi-token-cache-text', dt('dashboard.usageCacheHitRate', { rate: cacheRate }, '缓存命中 ' + cacheRate)); const total = Number(summary.totalTokens || 0); - const calls = Number(summary.modelCalls || 0); const today = res && res.today ? Number(res.today.totalTokens || 0) : 0; if (!Number.isFinite(total) || total <= 0) { setEl('dashboard-kpi-token-usage', '0'); @@ -731,10 +726,9 @@ function renderDashboardTokenUsage(res) { setEl('dashboard-kpi-token-usage', formatTokenUsageCompact(total)); setKpiSubText('dashboard-kpi-token-sub-text', dt('dashboard.tokenUsageSub', { - days: 7, today: formatTokenUsageCompact(today), - calls: Number.isFinite(calls) ? calls : 0 - }, '近 7 天 ' + (Number.isFinite(calls) ? calls : 0) + ' 次调用 · 今日 ' + formatTokenUsageCompact(today))); + rate: cacheRate + }, '今日 ' + formatTokenUsageCompact(today) + ' · 缓存命中 ' + cacheRate)); } function formatTokenUsageCompact(num) { diff --git a/web/static/js/token-usage-analysis.test.cjs b/web/static/js/token-usage-analysis.test.cjs index de24409d..9a39a482 100644 --- a/web/static/js/token-usage-analysis.test.cjs +++ b/web/static/js/token-usage-analysis.test.cjs @@ -75,7 +75,8 @@ test('all supported languages expose usage labels and interpolation placeholders for (const key of ['usageView', 'usageScope', 'usageCacheRead', 'usageCacheWrite', 'usageTrend', 'usageCacheHitRate']) assert.ok(data.dashboard[key]); assert.ok(data.settings.nav.tokenUsage); assert.match(data.dashboard.usageCacheHitRate, /\{\{rate\}\}/); - assert.match(data.dashboard.tokenUsageSub, /\{\{days\}\}/); + assert.match(data.dashboard.tokenUsageSub, /\{\{today\}\}/); + assert.match(data.dashboard.tokenUsageSub, /\{\{rate\}\}/); assert.match(data.chat.turnTokenUsageTitle, /\{\{cacheWrite\}\}/); } }); diff --git a/web/templates/index.html b/web/templates/index.html index ad0c85d9..949bc0f6 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -39,7 +39,7 @@ } })(); - + @@ -562,9 +562,8 @@