Skip to content

Fix dashboard statistics legend to include zero-usage users#656

Open
zhiqing0205 wants to merge 6 commits intoding113:devfrom
zhiqing0205:fix/dashboard-statistics-zero-usage-legend
Open

Fix dashboard statistics legend to include zero-usage users#656
zhiqing0205 wants to merge 6 commits intoding113:devfrom
zhiqing0205:fix/dashboard-statistics-zero-usage-legend

Conversation

@zhiqing0205
Copy link

@zhiqing0205 zhiqing0205 commented Jan 26, 2026

What

Fix a mismatch in the Dashboard statistics chart where users with zero usage were still rendered in the chart, but were missing from the user toggle buttons (legend) below.

Why

In Admin "Users" mode, the legend buttons control which user series are visible. Filtering out zero-usage users made them impossible to toggle, while their 0-value series still appeared in the chart.

Changes

  • Always render all users in StatisticsChartCard legend (including zero-usage users).
  • Add a unit test to ensure zero-usage users appear in the legend and remain toggleable.
  • Minor Biome lint cleanups (unused imports/params, hook deps) to keep bun run lint passing.

Greptile Overview

Greptile Summary

Fixed a UX inconsistency in the Dashboard statistics chart where users with zero usage were rendered in the chart but missing from the legend toggle buttons.

Key Changes:

  • Introduced nonZeroUsers memo to filter users with activity (cost > 0 OR calls > 0)
  • Updated legend rendering to show only nonZeroUsers while maintaining color consistency via originalIndex lookup
  • Modified "Select All" / "Deselect All" buttons to operate on nonZeroUsers instead of all users
  • Ensured visibleUsers filters from nonZeroUsers (not all users) to prevent rendering zero-usage series
  • Added comprehensive unit test verifying zero-usage users are excluded from both legend and chart series

Additional Changes:

  • Biome lint cleanups: removed unused imports, parameters, and fixed hook dependencies
  • Fixed flaky calendar test by using absolute dates instead of relative dates that could span month boundaries
  • Improved probe terminal auto-scroll hook to depend on lastLogId instead of entire logs array

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are well-structured and focused. The core fix properly addresses the legend/chart mismatch by introducing filtering logic that consistently excludes zero-usage users from both rendering and controls. The unit test validates the fix. All lint cleanups are routine maintenance removing genuinely unused code. The calendar test fix prevents date-boundary flakiness. No breaking changes or risky logic introduced.
  • No files require special attention

Important Files Changed

Filename Overview
src/app/[locale]/dashboard/_components/bento/statistics-chart-card.tsx Fixed legend to show only non-zero users while maintaining consistent chart rendering logic
tests/unit/dashboard/statistics-chart-card-legend-zero-usage.test.tsx Added test verifying zero-usage users are hidden from legend and chart series
src/app/[locale]/dashboard/availability/_components/endpoint/probe-terminal.tsx Fixed auto-scroll hook dependency and removed unused imports/variables
src/components/ui/tests/calendar-highlight.test.tsx Fixed flaky test by using fixed dates instead of relative dates that cross month boundaries

Sequence Diagram

sequenceDiagram
    participant User
    participant Component as StatisticsChartCard
    participant State as React State
    participant Memos as useMemo hooks
    participant Chart as AreaChart

    User->>Component: Load dashboard with user statistics
    Component->>State: Initialize selectedUserIds with all users
    Component->>Memos: Calculate userTotals (sum cost/calls per user)
    Memos-->>Component: Return totals for all users
    
    Component->>Memos: Filter nonZeroUsers (cost > 0 OR calls > 0)
    Memos-->>Component: Return only users with activity
    
    Component->>Memos: Filter visibleUsers (selected AND non-zero)
    Memos-->>Component: Return users to display in chart
    
    Component->>Chart: Render area series for visibleUsers only
    Chart-->>User: Display chart with visible user series
    
    Component->>Component: Render legend buttons for nonZeroUsers
    Component-->>User: Display toggleable buttons (zero-usage excluded)
    
    User->>Component: Click user toggle button
    Component->>State: Update selectedUserIds
    State-->>Component: Trigger re-render
    Component->>Memos: Recalculate visibleUsers
    Component->>Chart: Update chart with new visible users
    Chart-->>User: Display updated chart
Loading

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @zhiqing0205, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a user experience inconsistency in the dashboard's statistics chart. Previously, users who had no recorded usage would still appear in the chart visualization but were omitted from the interactive legend, making it impossible to toggle their visibility. This change ensures that all users, regardless of their usage metrics, are consistently represented in the legend, allowing for full control over chart data display. Additionally, the PR includes general code hygiene improvements by resolving several Biome linting issues.

Highlights

  • Dashboard Statistics Legend Fix: Users with zero usage are now correctly displayed in the StatisticsChartCard legend, resolving an inconsistency where they appeared in the chart but were untoggleable in the legend.
  • Unit Test Coverage: A new unit test has been added to specifically ensure that zero-usage users are present and toggleable in the statistics chart legend.
  • Biome Lint Cleanups: Several minor code cleanups were performed across various files, primarily removing unused imports, parameters, and addressing hook dependencies to ensure bun run lint passes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link

coderabbitai bot commented Jan 26, 2026

📝 Walkthrough

Walkthrough

将统计图表卡片的用户选择与渲染改为基于“非零使用”过滤:图表系列、图例与颜色映射仅针对有非零成本或调用的用户构建;同时清理若干无用导入/参数、调整少数 effect 依赖,并新增单元测试覆盖零使用场景。

Changes

Cohort / File(s) 变更摘要
统计图表卡片(非零使用过滤与渲染)
src/app/[locale]/dashboard/_components/bento/statistics-chart-card.tsx
引入 nonZeroUsersselectedNonZeroCount;改为基于非零用户计算 visibleUsersnumericChartDatatoggleUserSelection 保证过滤启用时至少保留一个非零用户;颜色映射改为使用用户在完整数据中的原始索引;图表渐变与系列遍历基于 visibleUsers
新增测试(验证零使用不在图例/系列中)
tests/unit/dashboard/statistics-chart-card-legend-zero-usage.test.tsx
新增单元测试:断言含零使用的用户不会出现在图例与系列中(模拟 next-intl 与 recharts)。
表单 effect 依赖调整
src/app/[locale]/dashboard/_components/user/forms/limit-rule-picker.tsx
将 reset 用的 useEffect 依赖从 [open, availableTypes] 简化为仅 [open]
探针终端与日志自动滚动
src/app/[locale]/dashboard/availability/_components/endpoint/probe-terminal.tsx
移除未用图标导入;增加在无日志时跳过自动滚动的守卫;自动滚动 effect 的依赖由整个日志数组改为 lastLogId;移除按级别的动态图标变量。
图表导入清理
src/app/[locale]/dashboard/availability/_components/endpoint/latency-curve.tsx, src/app/[locale]/dashboard/availability/_components/provider/latency-chart.tsx
移除 ResponsiveContainerChartTooltipContent 的导入;从 @/components/ui/chart 合并/调整为引入 type ChartConfig, ChartContainer, ChartTooltip
小型导入清理
src/app/[locale]/dashboard/availability/_components/endpoint/endpoint-tab.tsx, src/app/[locale]/settings/notifications/_components/global-settings-card.tsx, src/app/[locale]/settings/notifications/_components/webhook-targets-section.tsx, src/app/v1/_lib/proxy/forwarder.ts
删除若干未使用的导入(如 RefreshCw, Power, cn, Agent, ProxyConfigWithCacheKey),仅调整导入表面。
组件参数移除
src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/LogicTraceTab.tsx, src/app/[locale]/settings/providers/_components/forms/provider-form/index.tsx
从组件参数中移除未使用的 statusCodeallowedProviderTypes(签名不再接收这些 prop)。
lint 注释清理
src/app/[locale]/dashboard/logs/_hooks/use-lazy-filter-options.ts
删除 biome-ignore 的依赖穷尽注释,逻辑与依赖数组未变。
测试时间固定化
src/components/ui/__tests__/calendar-highlight.test.tsx
将基于今天的动态日期改为固定的月内日期(10号至15号),以稳定测试行为。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed 标题明确概括了主要变更:修复仪表板统计图表的图例,使其与零使用量用户的处理一致。
Description check ✅ Passed 描述清晰说明了问题、原因和解决方案,与实际代码变更相关,描述了零使用量用户的过滤处理。

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@github-actions github-actions bot added bug Something isn't working area:UI area:statistics size/XS Extra Small PR (< 50 lines) labels Jan 26, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request fixes a mismatch in the Dashboard statistics chart by ensuring that users with zero usage are included in the legend and remain toggleable. It also includes minor Biome lint cleanups. The changes primarily involve modifying the StatisticsChartCard component to remove a filter that excluded zero-usage users from the legend, adding a unit test to verify the fix, and removing unused imports/params in other files.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code Review Summary

This PR removes the filter that excluded zero-usage users from the statistics chart legend, allowing all users to be toggled regardless of their usage. The changes are clean and focused.

PR Size: XS

  • Lines changed: 115 (80 additions, 35 deletions)
  • Files changed: 13

Issues Found

Category Critical High Medium Low
Logic/Bugs 0 0 0 0
Security 0 0 0 0
Error Handling 0 0 0 0
Types 0 0 0 0
Comments/Docs 0 0 0 0
Tests 0 0 0 0
Simplification 0 0 0 0

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean
  • Type safety - Clean
  • Documentation accuracy - Clean
  • Test coverage - Adequate (new test added)
  • Code clarity - Good

Analysis

Main Change: The core fix in statistics-chart-card.tsx correctly removes the filter that was hiding zero-usage users from the legend while they still appeared in the chart. This resolves the mismatch described in the PR.

Lint Cleanups: The remaining changes are legitimate lint fixes:

  • Removed unused imports (RefreshCw, Trash2, Power, ChartTooltipContent, ResponsiveContainer, cn, Agent, ProxyConfigWithCacheKey)
  • Removed unused parameters (statusCode, allowedProviderTypes, Icon variable)
  • Fixed React hook dependencies appropriately

Test Coverage: A new unit test was added to verify zero-usage users appear in the legend, which is appropriate for this behavioral change.

Hook Dependency Changes:

  • limit-rule-picker.tsx: Removing availableTypes from deps is correct since it's now a constant reference to LIMIT_TYPE_OPTIONS
  • probe-terminal.tsx: Changed from logs to logs.length with early return guard - this is a valid optimization to prevent unnecessary effect runs when log content changes but length doesn't
  • use-lazy-filter-options.ts: Removed biome-ignore comment - the load callback correctly has no dependencies as fetcher is a stable closure parameter

All changes align with the stated purpose and follow project conventions.


Automated review by Claude AI

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@src/app/`[locale]/dashboard/availability/_components/endpoint/probe-terminal.tsx:
- Around line 75-81: The useEffect that auto-scrolls (the hook referencing
logs.length, autoScroll, userScrolled and containerRef) fails when the server
returns a same-length array; change the dependency from logs.length to a stable
identifier for the newest entry (e.g., compute lastLogId = logs[logs.length -
1]?.id or timestamp) and use that lastLogId in the effect dependencies along
with autoScroll and userScrolled, keep the same empty-array guard and scroll
logic inside the effect so new arrivals with identical length still trigger
auto-scroll.

@ding113 ding113 changed the base branch from main to dev January 27, 2026 12:58
@ding113
Copy link
Owner

ding113 commented Jan 27, 2026

According to the functional design, users with zero usage should not appear in the statistics chart; otherwise, it becomes difficult to make selections when the number of users is too large.

The expected modification here is for both the chart and the user list to be consistent in excluding zero-usage users.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@@ -399,10 +420,10 @@ export function StatisticsChartCard({
<div className="flex items-center justify-center gap-2 mb-2">
<button
onClick={() => setSelectedUserIds(new Set(data.users.map((u) => u.id)))}
Copy link

Choose a reason for hiding this comment

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

"Select All" button selects all users including zero-usage users, but only non-zero users appear in legend. This creates inconsistent state.

Suggested change
onClick={() => setSelectedUserIds(new Set(data.users.map((u) => u.id)))}
onClick={() => setSelectedUserIds(new Set(nonZeroUsers.map((u) => u.id)))}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/[locale]/dashboard/_components/bento/statistics-chart-card.tsx
Line: 422:422

Comment:
"Select All" button selects all users including zero-usage users, but only non-zero users appear in legend. This creates inconsistent state.

```suggestion
              onClick={() => setSelectedUserIds(new Set(nonZeroUsers.map((u) => u.id)))}
```

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:statistics area:UI bug Something isn't working size/XS Extra Small PR (< 50 lines)

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants