diff --git a/frontend/src/components/account/AccountUsageCell.vue b/frontend/src/components/account/AccountUsageCell.vue
index 0e5615120c..c1d7696b63 100644
--- a/frontend/src/components/account/AccountUsageCell.vue
+++ b/frontend/src/components/account/AccountUsageCell.vue
@@ -584,6 +584,7 @@
) => {
+ emit('account-updated', { ...props.account, opencode_go_usage: state })
+}
+
// ===== Key account today stats formatters =====
const formatKeyRequests = computed(() => {
diff --git a/frontend/src/components/account/OpenCodeGoUsageCell.vue b/frontend/src/components/account/OpenCodeGoUsageCell.vue
index 5dd7ee5c72..6ad8a8b736 100644
--- a/frontend/src/components/account/OpenCodeGoUsageCell.vue
+++ b/frontend/src/components/account/OpenCodeGoUsageCell.vue
@@ -38,23 +38,69 @@
>
{{ statusLabel }}
+
+
+
-
diff --git a/frontend/src/components/account/__tests__/OpenCodeGoUsageCell.spec.ts b/frontend/src/components/account/__tests__/OpenCodeGoUsageCell.spec.ts
index 0f7227993d..999b14ef1c 100644
--- a/frontend/src/components/account/__tests__/OpenCodeGoUsageCell.spec.ts
+++ b/frontend/src/components/account/__tests__/OpenCodeGoUsageCell.spec.ts
@@ -1,9 +1,21 @@
-import { mount } from '@vue/test-utils'
-import { describe, expect, it, vi } from 'vitest'
+import { flushPromises, mount } from '@vue/test-utils'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
import OpenCodeGoUsageCell from '../OpenCodeGoUsageCell.vue'
import UsageProgressBar from '../UsageProgressBar.vue'
import type { Account, OpenCodeGoUsageState } from '@/types'
+const { refreshOpenCodeGoUsage } = vi.hoisted(() => ({
+ refreshOpenCodeGoUsage: vi.fn()
+}))
+
+vi.mock('@/api/admin', () => ({
+ adminAPI: {
+ accounts: {
+ refreshOpenCodeGoUsage
+ }
+ }
+}))
+
vi.mock('vue-i18n', async () => {
const actual = await vi.importActual('vue-i18n')
return {
@@ -12,8 +24,8 @@ vi.mock('vue-i18n', async () => {
t: (key: string) => {
const short: Record = {
'admin.accounts.opencodeGo.rollingShort': '5h',
- 'admin.accounts.opencodeGo.weeklyShort': 'W',
- 'admin.accounts.opencodeGo.monthlyShort': 'M',
+ 'admin.accounts.opencodeGo.weeklyShort': '7d',
+ 'admin.accounts.opencodeGo.monthlyShort': '1m',
'admin.accounts.opencodeGo.unauthorized': 'unauthorized',
'admin.accounts.opencodeGo.failed': 'failed',
'admin.accounts.opencodeGo.ok': 'ok'
@@ -70,6 +82,10 @@ const account = (state = usageState()): Account => ({
})
describe('OpenCodeGoUsageCell', () => {
+ beforeEach(() => {
+ refreshOpenCodeGoUsage.mockReset()
+ })
+
it('renders rolling, weekly and monthly windows in a shrinkable mobile-safe cell', () => {
const wrapper = mount(OpenCodeGoUsageCell, { props: { account: account() } })
const cell = wrapper.get('[data-testid="opencode-go-usage-cell"]')
@@ -85,20 +101,35 @@ describe('OpenCodeGoUsageCell', () => {
color: 'indigo'
})
expect(bars[1].props()).toMatchObject({
- label: 'W',
+ label: '7d',
utilization: 14.2,
resetsAt: '2026-07-29T00:00:00Z',
color: 'emerald'
})
expect(bars[2].props()).toMatchObject({
- label: 'M',
+ label: '1m',
utilization: 33.3,
resetsAt: '2026-08-01T00:00:00Z',
color: 'amber'
})
expect(wrapper.find('[data-testid="opencode-go-status-badge"]').exists()).toBe(false)
- expect(wrapper.findAll('button')).toHaveLength(0)
+ const query = wrapper.get('[data-testid="opencode-go-usage-query"]')
+ expect(query.text()).toContain('admin.accounts.usageWindow.activeQuery')
+ })
+
+ it('refreshes usage on demand and emits the new state', async () => {
+ const next = usageState()
+ next.snapshot!.data!.rolling!.percent = 42
+ refreshOpenCodeGoUsage.mockResolvedValueOnce(next)
+ const wrapper = mount(OpenCodeGoUsageCell, { props: { account: account() } })
+
+ await wrapper.get('[data-testid="opencode-go-usage-query"]').trigger('click')
+ await flushPromises()
+
+ expect(refreshOpenCodeGoUsage).toHaveBeenCalledWith(7)
+ expect(wrapper.findAllComponents(UsageProgressBar)[0].props('utilization')).toBe(42)
+ expect(wrapper.emitted('updated')?.[0]?.[0]).toEqual(next)
})
it('shows a status badge when the snapshot status is not ok', () => {
diff --git a/frontend/src/i18n/locales/en/admin/accounts.ts b/frontend/src/i18n/locales/en/admin/accounts.ts
index 01f86e9c6c..89cf72ef84 100644
--- a/frontend/src/i18n/locales/en/admin/accounts.ts
+++ b/frontend/src/i18n/locales/en/admin/accounts.ts
@@ -309,9 +309,9 @@ export default {
rolling: '5 hour',
rollingShort: '5h',
weekly: 'Week',
- weeklyShort: 'W',
+ weeklyShort: '7d',
monthly: 'Month',
- monthlyShort: 'M',
+ monthlyShort: '1m',
status: 'Status',
updatedAt: 'Updated',
ok: 'Current',
diff --git a/frontend/src/i18n/locales/zh/admin/accounts.ts b/frontend/src/i18n/locales/zh/admin/accounts.ts
index ebf65505d2..690c68df85 100644
--- a/frontend/src/i18n/locales/zh/admin/accounts.ts
+++ b/frontend/src/i18n/locales/zh/admin/accounts.ts
@@ -185,9 +185,9 @@ export default {
rolling: '5 小时',
rollingShort: '5h',
weekly: '周',
- weeklyShort: '周',
+ weeklyShort: '7d',
monthly: '月',
- monthlyShort: '月',
+ monthlyShort: '1m',
status: '状态',
updatedAt: '更新时间',
ok: '正常',