style(usage): keep statistic card metadata on one line
This commit is contained in:
1 parent
5924faaac3
commit
d59cee19fa
4 files changed
+21
-20
No files matched your search
+5
-5
@@ -128,16 +128,16 @@ export const jaOverrides = {
|
||||
'usage.stat.requests': '総リクエスト数',
|
||||
'usage.stat.requestMeta': '成功 {success} · 失敗 {failed}',
|
||||
'usage.stat.tokens': '合計 Token',
|
||||
'usage.stat.tokenMeta': '入力 {input} · 出力 {output}',
|
||||
'usage.stat.tokenMeta': '入 {input} · 出 {output}',
|
||||
'usage.stat.successRate': '成功率',
|
||||
'usage.stat.reasoningMeta': '推論 {tokens} Token',
|
||||
'usage.stat.reasoningMeta': '推論 {tokens}',
|
||||
'usage.stat.averageLatency': '平均レイテンシ',
|
||||
'usage.stat.tps': 'TPS',
|
||||
'usage.stat.performanceMeta': '{rpm} RPM · 平均レイテンシ {latency} ms',
|
||||
'usage.stat.performanceMeta': 'RPM {rpm} · {latency} ms',
|
||||
'usage.stat.cacheHitRate': 'キャッシュヒット率',
|
||||
'usage.stat.cacheHitMeta': 'ヒット {hit} / 入力 {input} Token',
|
||||
'usage.stat.cacheHitMeta': 'キャッシュ {hit}/{input}',
|
||||
'usage.stat.estimatedCost': '推定コスト',
|
||||
'usage.stat.costMeta': '{priced} / {total} 件を計算済み · 参考値',
|
||||
'usage.stat.costMeta': '計算 {priced}/{total} · 推定',
|
||||
'usage.pricing.coverage': '{priced} / {total} 件を計算済み · 利用可能なモデル料金 {saved} 件',
|
||||
'usage.pricing.search': 'モデルを検索',
|
||||
'usage.pricing.add': '手動で追加',
|
||||
|
||||
+12
-12
@@ -129,18 +129,18 @@ export const zhCN = {
|
||||
'usage.filter.to': '至',
|
||||
'usage.loading': '正在读取本地 SQLite 使用记录',
|
||||
'usage.stat.requests': '请求总数',
|
||||
'usage.stat.requestMeta': '{success} 成功 · {failed} 失败',
|
||||
'usage.stat.requestMeta': '成功 {success} · 失败 {failed}',
|
||||
'usage.stat.tokens': 'Token 总量',
|
||||
'usage.stat.tokenMeta': '输入 {input} · 输出 {output}',
|
||||
'usage.stat.tokenMeta': '入 {input} · 出 {output}',
|
||||
'usage.stat.successRate': '成功率',
|
||||
'usage.stat.reasoningMeta': '思考 {tokens} Token',
|
||||
'usage.stat.reasoningMeta': '思考 {tokens}',
|
||||
'usage.stat.averageLatency': '平均延迟',
|
||||
'usage.stat.tps': 'TPS',
|
||||
'usage.stat.performanceMeta': '{rpm} RPM · 平均延迟 {latency} ms',
|
||||
'usage.stat.performanceMeta': 'RPM {rpm} · {latency} ms',
|
||||
'usage.stat.cacheHitRate': '缓存命中率',
|
||||
'usage.stat.cacheHitMeta': '命中 {hit} / 输入 {input} Token',
|
||||
'usage.stat.cacheHitMeta': '缓存 {hit}/{input}',
|
||||
'usage.stat.estimatedCost': '预估成本',
|
||||
'usage.stat.costMeta': '已计价 {priced} / {total} 次请求 · 仅供参考',
|
||||
'usage.stat.costMeta': '计价 {priced}/{total} · 估算',
|
||||
'usage.pricing.coverage': '已计价 {priced} / {total} 次请求 · 可用 {saved} 个模型价格',
|
||||
'usage.pricing.search': '搜索模型',
|
||||
'usage.pricing.add': '手动添加',
|
||||
@@ -1018,18 +1018,18 @@ export const en: Record<MessageKey, string> = {
|
||||
'usage.filter.to': 'to',
|
||||
'usage.loading': 'Loading local SQLite usage history',
|
||||
'usage.stat.requests': 'Total Requests',
|
||||
'usage.stat.requestMeta': '{success} succeeded · {failed} failed',
|
||||
'usage.stat.requestMeta': 'OK {success} · Fail {failed}',
|
||||
'usage.stat.tokens': 'Total Tokens',
|
||||
'usage.stat.tokenMeta': 'Input {input} · Output {output}',
|
||||
'usage.stat.tokenMeta': 'In {input} · Out {output}',
|
||||
'usage.stat.successRate': 'Success Rate',
|
||||
'usage.stat.reasoningMeta': 'Reasoning {tokens} tokens',
|
||||
'usage.stat.reasoningMeta': 'Reasoning {tokens}',
|
||||
'usage.stat.averageLatency': 'Average Latency',
|
||||
'usage.stat.tps': 'TPS',
|
||||
'usage.stat.performanceMeta': '{rpm} RPM · Avg latency {latency} ms',
|
||||
'usage.stat.performanceMeta': 'RPM {rpm} · {latency} ms',
|
||||
'usage.stat.cacheHitRate': 'Cache Hit Rate',
|
||||
'usage.stat.cacheHitMeta': '{hit} hit / {input} input tokens',
|
||||
'usage.stat.cacheHitMeta': 'Cache {hit}/{input}',
|
||||
'usage.stat.estimatedCost': 'Estimated Cost',
|
||||
'usage.stat.costMeta': '{priced} / {total} requests priced · Estimate only',
|
||||
'usage.stat.costMeta': 'Priced {priced}/{total} · Est.',
|
||||
'usage.pricing.coverage': '{priced} / {total} requests priced · {saved} model prices available',
|
||||
'usage.pricing.search': 'Search model',
|
||||
'usage.pricing.add': 'Add Manually',
|
||||
|
||||
@@ -414,7 +414,7 @@ export function UsageRecordsPage() {
|
||||
function OverviewView({ overview }: { overview: UsageOverview }) {
|
||||
const { t } = useI18n();
|
||||
const cards = [
|
||||
{ icon: Activity, label: t('usage.stat.requests'), value: compactNumber(overview.totalRequests), meta: t('usage.stat.requestMeta', { success: overview.successCount, failed: overview.failureCount }) },
|
||||
{ icon: Activity, label: t('usage.stat.requests'), value: compactNumber(overview.totalRequests), meta: t('usage.stat.requestMeta', { success: compactNumber(overview.successCount), failed: compactNumber(overview.failureCount) }) },
|
||||
{ icon: Sparkles, label: t('usage.stat.tokens'), value: compactNumber(overview.totalTokens), meta: t('usage.stat.tokenMeta', { input: compactNumber(overview.inputTokens), output: compactNumber(overview.outputTokens) }) },
|
||||
{ icon: ShieldCheck, label: t('usage.stat.successRate'), value: `${overview.successRate.toFixed(1)}%`, meta: t('usage.stat.reasoningMeta', { tokens: compactNumber(overview.reasoningTokens) }) },
|
||||
{ icon: Clock3, label: t('usage.stat.tps'), value: `${overview.tps.toFixed(1)} TPS`, meta: t('usage.stat.performanceMeta', { rpm: overview.rpm.toFixed(2), latency: Math.round(overview.averageLatencyMs) }) },
|
||||
@@ -422,7 +422,7 @@ function OverviewView({ overview }: { overview: UsageOverview }) {
|
||||
{ icon: CircleDollarSign, label: t('usage.stat.estimatedCost'), value: formatUsd(overview.estimatedCost), meta: t('usage.stat.costMeta', { priced: compactNumber(overview.pricedRequests), total: compactNumber(overview.totalRequests) }) },
|
||||
];
|
||||
return <div className="usage-overview-layout">
|
||||
<div className="usage-stat-grid">{cards.map(({ icon: Icon, label, value, meta }) => <article className="panel usage-stat-card" key={label}><span><Icon size={16} />{label}</span><strong>{value}</strong><small>{meta}</small></article>)}</div>
|
||||
<div className="usage-stat-grid">{cards.map(({ icon: Icon, label, value, meta }) => <article className="panel usage-stat-card" key={label}><span><Icon size={16} />{label}</span><strong>{value}</strong><small title={meta}>{meta}</small></article>)}</div>
|
||||
<section className="panel usage-trend-panel"><div className="usage-section-heading"><div><strong>{t('usage.trend.title')}</strong><span>{t('usage.trend.description')}</span></div></div>{overview.timeline.length ? <UsageTrend points={overview.timeline} /> : <UsageEmpty />}</section>
|
||||
<section className="panel usage-health-panel"><div className="usage-section-heading"><div><strong>{t('usage.token.title')}</strong><span>{t('usage.token.description')}</span></div></div><div className="usage-token-breakdown"><TokenMetric label={t('usage.token.input')} value={overview.inputTokens} total={overview.totalTokens} /><TokenMetric label={t('usage.token.output')} value={overview.outputTokens} total={overview.totalTokens} /><TokenMetric label={t('usage.token.reasoning')} value={overview.reasoningTokens} total={overview.totalTokens} /><TokenMetric label={t('usage.token.cacheRead')} value={overview.cacheReadTokens} total={overview.totalTokens} /><TokenMetric label={t('usage.token.cacheCreation')} value={overview.cacheCreationTokens} total={overview.totalTokens} /></div></section>
|
||||
</div>;
|
||||
|
||||
+2
-1
@@ -5749,11 +5749,12 @@ textarea:focus-visible {
|
||||
|
||||
.usage-stat-card > small {
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
color: var(--theme-8a847c);
|
||||
font-size: var(--font-size-caption);
|
||||
line-height: var(--line-height-body);
|
||||
text-overflow: ellipsis;
|
||||
white-space: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.usage-trend-panel,
|
||||
|
||||
Reference in new issue
Block a user