fix(dashboard): label remaining quota basis (#26)

This commit is contained in:
Eyejoker
2026-04-27 00:32:18 +09:00
committed by GitHub
parent 19afc76b89
commit 84d910de14
2 changed files with 31 additions and 2 deletions

View File

@@ -28,6 +28,7 @@ type UsageRow = DashboardOverview['usage']['rows'][number];
type InboxItem = DashboardOverview['inbox'][number]; type InboxItem = DashboardOverview['inbox'][number];
type RiskLevel = 'ok' | 'warn' | 'critical'; type RiskLevel = 'ok' | 'warn' | 'critical';
type UsageGroup = 'primary' | 'codex'; type UsageGroup = 'primary' | 'codex';
type UsageLimitWindow = 'h5' | 'd7';
type DashboardView = 'usage' | 'inbox' | 'health' | 'rooms' | 'scheduled'; type DashboardView = 'usage' | 'inbox' | 'health' | 'rooms' | 'scheduled';
type TaskGroupKey = 'watchers' | 'scheduled' | 'paused' | 'completed'; type TaskGroupKey = 'watchers' | 'scheduled' | 'paused' | 'completed';
type TaskResultTone = 'ok' | 'fail' | 'none'; type TaskResultTone = 'ok' | 'fail' | 'none';
@@ -145,6 +146,10 @@ function usageRemaining(row: UsageRow): number | null {
return Math.max(0, 100 - peak); return Math.max(0, 100 - peak);
} }
function usageLimitWindow(row: UsageRow): UsageLimitWindow {
return row.d7pct >= row.h5pct ? 'd7' : 'h5';
}
function usageRiskLevel(row: UsageRow): RiskLevel { function usageRiskLevel(row: UsageRow): RiskLevel {
const peak = usagePeak(row); const peak = usagePeak(row);
if (peak >= 85) return 'critical'; if (peak >= 85) return 'critical';
@@ -174,7 +179,7 @@ function usageNameParts(row: UsageRow): {
} }
function usageLimitReset(row: UsageRow): string { function usageLimitReset(row: UsageRow): string {
return (row.d7pct >= row.h5pct ? row.d7reset : row.h5reset).trim(); return (usageLimitWindow(row) === 'd7' ? row.d7reset : row.h5reset).trim();
} }
function usageBurnRate(row: UsageRow): number | null { function usageBurnRate(row: UsageRow): number | null {
@@ -925,6 +930,7 @@ function UsageRemainingMeter({
t: Messages; t: Messages;
}) { }) {
const remaining = usageRemaining(row); const remaining = usageRemaining(row);
const window = usageLimitWindow(row);
const reset = usageLimitReset(row); const reset = usageLimitReset(row);
return ( return (
@@ -940,7 +946,10 @@ function UsageRemainingMeter({
max={100} max={100}
value={remaining ?? 0} value={remaining ?? 0}
/> />
<small>{reset ? `${t.usage.reset} ${reset}` : t.usage.noReset}</small> <small>
{remaining === null ? '-' : t.usage.limitBasis[window]}
{reset ? ` · ${t.usage.reset} ${reset}` : ` · ${t.usage.noReset}`}
</small>
</div> </div>
); );
} }

View File

@@ -126,6 +126,10 @@ export interface Messages {
inUse: string; inUse: string;
reset: string; reset: string;
noReset: string; noReset: string;
limitBasis: {
h5: string;
d7: string;
};
usage: string; usage: string;
groupPrimary: string; groupPrimary: string;
groupCodex: string; groupCodex: string;
@@ -327,6 +331,10 @@ export const messages = {
inUse: '사용중', inUse: '사용중',
reset: '리셋', reset: '리셋',
noReset: '리셋 없음', noReset: '리셋 없음',
limitBasis: {
h5: '5시간 기준',
d7: '7일 기준',
},
usage: '사용량', usage: '사용량',
groupPrimary: 'Claude / Kimi', groupPrimary: 'Claude / Kimi',
groupCodex: 'Codex', groupCodex: 'Codex',
@@ -512,6 +520,10 @@ export const messages = {
inUse: 'in use', inUse: 'in use',
reset: 'reset', reset: 'reset',
noReset: 'no reset', noReset: 'no reset',
limitBasis: {
h5: '5h basis',
d7: '7d basis',
},
usage: 'usage', usage: 'usage',
groupPrimary: 'Claude / Kimi', groupPrimary: 'Claude / Kimi',
groupCodex: 'Codex', groupCodex: 'Codex',
@@ -697,6 +709,10 @@ export const messages = {
inUse: '使用中', inUse: '使用中',
reset: '重置', reset: '重置',
noReset: '无重置', noReset: '无重置',
limitBasis: {
h5: '按5小时',
d7: '按7天',
},
usage: '用量', usage: '用量',
groupPrimary: 'Claude / Kimi', groupPrimary: 'Claude / Kimi',
groupCodex: 'Codex', groupCodex: 'Codex',
@@ -882,6 +898,10 @@ export const messages = {
inUse: '使用中', inUse: '使用中',
reset: 'リセット', reset: 'リセット',
noReset: 'リセットなし', noReset: 'リセットなし',
limitBasis: {
h5: '5時間基準',
d7: '7日基準',
},
usage: '使用量', usage: '使用量',
groupPrimary: 'Claude / Kimi', groupPrimary: 'Claude / Kimi',
groupCodex: 'Codex', groupCodex: 'Codex',