Skip to content

refactor: codex usage ui - #5595

Merged
seefs001 merged 3 commits into
QuantumNous:mainfrom
seefs001:refactor/codex-usage-0618
Jun 19, 2026
Merged

refactor: codex usage ui#5595
seefs001 merged 3 commits into
QuantumNous:mainfrom
seefs001:refactor/codex-usage-0618

Conversation

@seefs001

@seefs001 seefs001 commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)

codex 账号信息 增加重置次数展示,调整ui展示,增加重置flow

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)

Summary by CodeRabbit

  • UI/UX Improvements
    • Refreshed the Codex usage modal/dialog with a redesigned rate-limit layout, responsive styling, standardized info fields, and improved section organization (including collapsible “Reset Credits” and “Raw JSON”).
    • Improved reset/usage reset presentation with clearer timing text and progress/status badge behavior.
  • New Features
    • Added confirmation flow for applying a usage reset, including reset-credit details and reloading after actions.
  • API/Backend
    • Added admin codex endpoints to fetch reset credits and to perform usage resets; centralized Codex Wham request header handling.
  • Localization
    • Added new Codex/reset-credit strings across multiple languages (including status, reset timing, and error/success messaging).

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Implements end-to-end reset-credit functionality for Codex usage: backend generalization of fetch logic, new reset-credit consume endpoint, overhauled UI in both dialog and modal with Account Status card and reset-credits panel, and i18n support across six locales.

Changes

Codex Usage Reset Credits Full Stack

Layer / File(s) Summary
Backend fetch generalization and routing
controller/codex_usage.go, router/api-router.go
Refactors GetCodexChannelUsage, GetCodexChannelRateLimitResetCredits, and ResetCodexChannelUsage handlers to use shared fetchCodexChannelWhamData helper that accepts injected fetch functions; adds GET reset-credits and POST reset routes.
Service layer HTTP helpers and consume endpoint
service/codex_wham_usage.go
Centralizes Codex Wham HTTP headers via setCodexWhamRequestHeaders helper; updates existing fetch functions to use it; adds ConsumeCodexWhamRateLimitResetCredit POST endpoint with generated redeem_request_id payload.
API response types and wrapper functions
web/default/src/features/channels/api.ts
Adds CodexResetCreditsResponse and CodexUsageResetResponse type aliases; introduces getCodexResetCredits and resetCodexUsage API wrapper functions with duplicate-suppression config.
Payload types, helpers, and reset-credit utilities
web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx
Updates CodexUsagePayload with rate_limit_reset_credits, credits.overage_limit_reached, and spend_control.reached fields (removes account_id); adds helpers for timestamp formatting, time-left calculation, reset-credit parsing/sorting/normalization; introduces status badge mapping and utility functions for usage status, formatted labels, and percent text styling.
Reusable InfoField and SectionHeading components
web/classic/src/components/.../CodexUsageModal.jsx, web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx
Introduces InfoField component (monospace text, optional copy-to-clipboard button) and SectionHeading component in both modal and dialog, replacing older AccountInfoValue helper and standardizing section headers.
Rate-limit window and group section UI components
web/classic/src/components/.../CodexUsageModal.jsx, web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx
Redesigns RateLimitWindowCard (classic modal) and introduces RateLimitWindow/RateLimitWindowGrid (default dialog) with compact card layout, disabled progress info display, reset timing fields ("Reset at" / "Resets in"), and usage status badge integration in RateLimitGroupSection.
Classic modal CSS injection and responsive layout
web/classic/src/components/.../CodexUsageModal.jsx
Adds CODEX_USAGE_MODAL_CLASS_NAME constant and CodexUsageModalStyles CSS-injection component for responsive mobile/desktop sizing; adjusts modal top, margin, and bodyStyle.maxHeight in getCodexUsageModalLayout; applies class name to Modal.info.
Classic CodexUsageView and CodexUsageLoader rewrite
web/classic/src/components/.../CodexUsageModal.jsx
Derives channelLabel and resetCredits from payload; restructures CodexUsageView with error banner, account status tags, InfoField identity section, "Basic" and "Additional" quota sections, and updated collapse styling; wraps CodexUsageLoader states with CodexUsageModalStyles; reduces raw JSON max-height.
Default dialog state, async loading, and reset confirmation
web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx
Adds dialog state for "Reset Credits" collapsible, loading/error states, and reset-credit payload selection; implements loadResetCredits async fetch; adds handleConfirmReset to apply reset, refresh upstream usage, and reload reset-credit details.
Default dialog body layout and Account Status card
web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx
Rebuilds Dialog with error banner, "Account Status" Card (plan, usage status, HTTP upstream, reset count, overage/spend-limited badges), InfoField identity section, base/additional rate-limit sections via RateLimitWindowGrid, and collapsible "Reset Credits" with ResetCreditsPanel.
Default dialog Raw JSON section and reset confirmation flow
web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx
Restructures "Raw JSON" collapsible with updated copy icon styling; adds ConfirmDialog for reset confirmation with channel/reset-credit summary and async reset handler wiring.
i18n support across six locales
web/default/src/i18n/locales/en.json, fr.json, ja.json, ru.json, vi.json, zh.json
Adds 39 new translation keys per locale for reset-credit UI, status labels ("Codex Account Status", "Overage limited", "Spend limited"), error/confirmation messages, and supporting account/reset-credit wording.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

  • QuantumNous/new-api#2652: Adds the core Codex channel endpoint and FetchCodexWhamUsage service; this PR extends that same backend layer with ConsumeCodexWhamRateLimitResetCredit and refactors shared fetch logic.
  • QuantumNous/new-api#3399: Directly overlaps at the CodexUsageModal component level—both refactor the modal's header, account-status rendering, and JSON display layout.
  • QuantumNous/new-api#4386: Both PRs refactor responsive layout and rate-limit window/group rendering in the Codex usage modal, including mobile-aware sizing and redesigned RateLimitWindow/RateLimitGroupSection components.

Poem

🐇 Hippity-hop, reset credits bloom,
From backend to UI—no more gloom!
Shared fetch helpers, consume endpoints flow,
Across six locales, translations grow.
The rabbit refactored top, bottom, and side,
Codex usage reset—with nowhere to hide! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor: codex usage ui' accurately summarizes the primary changes across the codebase, which focus on refactoring the Codex usage dialog and modal UI components with improved layout, styling, and presentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx (3)

347-362: ⚡ Quick win

Consider extracting props to a named interface.

While inline prop typing works, extracting to a named interface improves code organization and reusability, especially as this component is used multiple times throughout the dialog.

♻️ Suggested refactor
+interface RateLimitWindowGridProps {
+  fiveHourWindow?: CodexRateLimitWindow | null
+  weeklyWindow?: CodexRateLimitWindow | null
+}
+
-function RateLimitWindowGrid(props: {
-  fiveHourWindow?: CodexRateLimitWindow | null
-  weeklyWindow?: CodexRateLimitWindow | null
-}) {
+function RateLimitWindowGrid(props: RateLimitWindowGridProps) {
   const { t } = useTranslation()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx`
around lines 347 - 362, Extract the inline prop typing from the
RateLimitWindowGrid component into a named interface. Create a new interface
(e.g., RateLimitWindowGridProps) that defines the fiveHourWindow and
weeklyWindow properties with their types (CodexRateLimitWindow or null), then
replace the inline props parameter in the RateLimitWindowGrid function signature
with this named interface to improve code organization and reusability.

364-386: ⚡ Quick win

Consider extracting props to a named interface.

For consistency with TypeScript best practices and improved maintainability, extract the props to a separate interface declaration.

♻️ Suggested refactor
+interface SectionHeadingProps {
+  title: string
+  description?: string
+  children?: ReactNode
+}
+
-function SectionHeading(props: {
-  title: string
-  description?: string
-  children?: ReactNode
-}) {
+function SectionHeading(props: SectionHeadingProps) {
   return (
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx`
around lines 364 - 386, The SectionHeading function currently defines its props
type inline as an anonymous object type. Extract this props definition into a
separate named interface (e.g., SectionHeadingProps) declared above the
SectionHeading function, then update the function parameter to use this new
interface instead of the inline type definition.

423-468: ⚡ Quick win

Consider extracting props to a named interface.

Following TypeScript best practices, extract the inline props definition to a separate interface for better code organization.

♻️ Suggested refactor
+interface InfoFieldProps {
+  label: string
+  value?: string | null
+  mono?: boolean
+  copyable?: boolean
+  className?: string
+}
+
-function InfoField(props: {
-  label: string
-  value?: string | null
-  mono?: boolean
-  copyable?: boolean
-  className?: string
-}) {
+function InfoField(props: InfoFieldProps) {
   const { t } = useTranslation()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx`
around lines 423 - 468, Extract the inline props object type definition from the
InfoField function into a separate named interface called InfoFieldProps. Define
this interface above the InfoField function with the same properties (label,
value, mono, copyable, and className), then update the function signature to use
this new interface type instead of the inline object definition. This improves
code organization and makes the props contract more explicit and reusable.
web/classic/src/components/table/channels/modals/CodexUsageModal.jsx (1)

37-48: 💤 Low value

Consider alternatives to inline style injection with !important.

While this works, injecting <style> tags in components and using !important to override library styles creates maintainability issues and breaks CSS specificity rules.

Consider these alternatives:

  1. Use CSS modules or a separate stylesheet
  2. Use Semi-UI's theme customization APIs if available
  3. Use a CSS-in-JS solution like styled-components
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/classic/src/components/table/channels/modals/CodexUsageModal.jsx` around
lines 37 - 48, The CodexUsageModalStyles function uses inline style injection
with !important to override Semi-UI library styles, which creates
maintainability issues and breaks CSS specificity. Replace this approach by
moving the media query styles for CODEX_USAGE_MODAL_CLASS_NAME and
MOBILE_BREAKPOINT to either a separate CSS module, a dedicated stylesheet, or
use Semi-UI's theme customization APIs if available. Remove the !important
declarations and rely on proper CSS specificity instead. If using a CSS-in-JS
solution like styled-components, migrate the CodexUsageModalStyles styles
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx`:
- Around line 238-240: The function formatLabelValue lacks explicit type
annotations for its parameters and return type. Add explicit type annotations to
both parameters (label and value should be typed as string) and add an explicit
return type annotation (: string) to the function declaration to comply with
TypeScript coding guidelines.
- Around line 221-236: The function getUsageStatusBadge is missing an explicit
return type annotation on its signature. Add the return type annotation to the
function declaration, specifying that it returns a JSX.Element (or the
appropriate React element type) since all code paths in the function return
StatusBadge components.

---

Nitpick comments:
In `@web/classic/src/components/table/channels/modals/CodexUsageModal.jsx`:
- Around line 37-48: The CodexUsageModalStyles function uses inline style
injection with !important to override Semi-UI library styles, which creates
maintainability issues and breaks CSS specificity. Replace this approach by
moving the media query styles for CODEX_USAGE_MODAL_CLASS_NAME and
MOBILE_BREAKPOINT to either a separate CSS module, a dedicated stylesheet, or
use Semi-UI's theme customization APIs if available. Remove the !important
declarations and rely on proper CSS specificity instead. If using a CSS-in-JS
solution like styled-components, migrate the CodexUsageModalStyles styles
accordingly.

In `@web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx`:
- Around line 347-362: Extract the inline prop typing from the
RateLimitWindowGrid component into a named interface. Create a new interface
(e.g., RateLimitWindowGridProps) that defines the fiveHourWindow and
weeklyWindow properties with their types (CodexRateLimitWindow or null), then
replace the inline props parameter in the RateLimitWindowGrid function signature
with this named interface to improve code organization and reusability.
- Around line 364-386: The SectionHeading function currently defines its props
type inline as an anonymous object type. Extract this props definition into a
separate named interface (e.g., SectionHeadingProps) declared above the
SectionHeading function, then update the function parameter to use this new
interface instead of the inline type definition.
- Around line 423-468: Extract the inline props object type definition from the
InfoField function into a separate named interface called InfoFieldProps. Define
this interface above the InfoField function with the same properties (label,
value, mono, copyable, and className), then update the function signature to use
this new interface type instead of the inline object definition. This improves
code organization and makes the props contract more explicit and reusable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f5997acc-d422-439b-804a-a1444e199d4e

📥 Commits

Reviewing files that changed from the base of the PR and between f7dae5c and a37bf4b.

📒 Files selected for processing (8)
  • web/classic/src/components/table/channels/modals/CodexUsageModal.jsx
  • web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json

Comment on lines +221 to +236
function getUsageStatusBadge(
rateLimit: CodexRateLimit | undefined,
t: (key: string) => string
) {
if (!rateLimit || Object.keys(rateLimit).length === 0) {
return (
<StatusBadge label={t('Pending')} variant='neutral' copyable={false} />
)
}
if (rateLimit.allowed && !rateLimit.limit_reached) {
return (
<StatusBadge label={t('Available')} variant='success' copyable={false} />
)
}
return <StatusBadge label={t('Limited')} variant='danger' copyable={false} />
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add explicit parameter and return type annotations.

As per coding guidelines, TypeScript functions should explicitly annotate parameter and return value types.

♻️ Proposed fix
-function getUsageStatusBadge(
-  rateLimit: CodexRateLimit | undefined,
-  t: (key: string) => string
-) {
+function getUsageStatusBadge(
+  rateLimit: CodexRateLimit | undefined,
+  t: (key: string) => string
+): JSX.Element {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function getUsageStatusBadge(
rateLimit: CodexRateLimit | undefined,
t: (key: string) => string
) {
if (!rateLimit || Object.keys(rateLimit).length === 0) {
return (
<StatusBadge label={t('Pending')} variant='neutral' copyable={false} />
)
}
if (rateLimit.allowed && !rateLimit.limit_reached) {
return (
<StatusBadge label={t('Available')} variant='success' copyable={false} />
)
}
return <StatusBadge label={t('Limited')} variant='danger' copyable={false} />
}
function getUsageStatusBadge(
rateLimit: CodexRateLimit | undefined,
t: (key: string) => string
): JSX.Element {
if (!rateLimit || Object.keys(rateLimit).length === 0) {
return (
<StatusBadge label={t('Pending')} variant='neutral' copyable={false} />
)
}
if (rateLimit.allowed && !rateLimit.limit_reached) {
return (
<StatusBadge label={t('Available')} variant='success' copyable={false} />
)
}
return <StatusBadge label={t('Limited')} variant='danger' copyable={false} />
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx`
around lines 221 - 236, The function getUsageStatusBadge is missing an explicit
return type annotation on its signature. Add the return type annotation to the
function declaration, specifying that it returns a JSX.Element (or the
appropriate React element type) since all code paths in the function return
StatusBadge components.

Source: Coding guidelines

Comment on lines +238 to +240
function formatLabelValue(label: string, value: string) {
return label.endsWith(':') ? `${label}${value}` : `${label} ${value}`
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add explicit parameter and return type annotations.

As per coding guidelines, all TypeScript functions should have explicit type annotations.

♻️ Proposed fix
-function formatLabelValue(label: string, value: string) {
+function formatLabelValue(label: string, value: string): string {
   return label.endsWith(':') ? `${label}${value}` : `${label} ${value}`
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/channels/components/dialogs/codex-usage-dialog.tsx`
around lines 238 - 240, The function formatLabelValue lacks explicit type
annotations for its parameters and return type. Add explicit type annotations to
both parameters (label and value should be typed as string) and add an explicit
return type annotation (: string) to the function declaration to comply with
TypeScript coding guidelines.

Source: Coding guidelines

@seefs001
seefs001 merged commit 3fcd741 into QuantumNous:main Jun 19, 2026
1 check was pending
@coderabbitai coderabbitai Bot mentioned this pull request Jun 26, 2026
11 tasks
ruanhangjian pushed a commit to ruanhangjian/new-api that referenced this pull request Jul 11, 2026
* refactor: codex usage ui

* feat: show Codex reset credit details

* feat: add Codex usage reset flow
zhaodechao2008 pushed a commit to zhaodechao2008/new-api that referenced this pull request Jul 27, 2026
* refactor: codex usage ui

* feat: show Codex reset credit details

* feat: add Codex usage reset flow
330079598 pushed a commit to 330079598/new-api that referenced this pull request Aug 19, 2026
* refactor: codex usage ui

* feat: show Codex reset credit details

* feat: add Codex usage reset flow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant