feat(dashboard): add token usage by model & user dimension with tab visibility control - #4329
feat(dashboard): add token usage by model & user dimension with tab visibility control#4329rangerTao wants to merge 8 commits into
Conversation
- Add model_name filter parameter to all /api/data/ endpoints (backend) - Add model name input field to dashboard SearchModal (frontend) - Add new "Token Usage Distribution" stacked bar chart tab - Extend data aggregation to include token_used field - Add i18n translations for 7 locales
- Add "User Token Ranking" horizontal bar chart (admin) - Add "User Token Trend" area chart (admin) - Extend processUserData to aggregate token_used per user - Add i18n translations for 7 locales
- Add DataDashboardChartTabs global setting (admin, comma-separated keys) - Add CheckboxGroup in dashboard settings for admin to select visible tabs - Add per-user tab preference via Popover settings button (localStorage) - Priority: user preference > admin global > show all - Add i18n translations for 7 locales
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThis PR introduces model-dimension filtering and chart tab visibility controls to the data dashboard. It adds a global ChangesDashboard Model Filtering & Tab Visibility
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/dashboard/ChartsPanel.jsx`:
- Around line 127-161: Replace the bare Settings SVG used as the Popover trigger
with the existing Semi Button so keyboard and screen-reader users can open the
chart settings; specifically, wrap or render a <Button> (use size='small'
type='tertiary' and keep the current classes) as the Popover children trigger
instead of the plain Settings icon, pass the Settings icon via the Button's icon
prop, and add an accessible label such as aria-label={t('图表显示设置')} (or title) so
assistive tech and keyboard focus can activate the Popover while preserving
behavior tied to checkedUserTabs, handleUserTabsChange and handleResetUserTabs.
In `@web/src/i18n/locales/zh-TW.json`:
- Around line 2092-2093: The new translations were added under a nested
"translation" object instead of the required flat JSON shape; move the keys
"图表显示设置" and "可见图表" out of any nested "translation" object and place them as
top-level keys in zh-TW.json with their values ("圖表顯示設定", "可見圖表"), then run the
project's i18n sync/extraction script (the same tooling used for other locale
updates) to ensure the file shape and key ordering match the project's flat JSON
guideline and update any related locale entries mentioned (3206-3208).
In `@web/src/pages/Setting/Dashboard/SettingsDataDashboard.jsx`:
- Around line 167-180: The current logic treats an empty string as “all charts”
because DataDashboardChartTabs === '' is used for the all-selected case; change
the encoding so empty selection is distinct (e.g. use a sentinel like '__NONE__'
or null) and update both the value and onChange handling for
DataDashboardChartTabs: when building the value for the checkbox group, map the
sentinel to an empty array instead of ALL_CHART_TABS, and in setInputs (inside
the onChange handler) store the sentinel when checkedValues.length === 0, store
'' (or the existing all-sentinel) when checkedValues length equals
ALL_CHART_TABS.length, otherwise store checkedValues.join(','); update any
consumers that interpret DataDashboardChartTabs to respect the new
empty-selection sentinel.
🪄 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: 001b54f5-1eee-4ea5-8e70-5d627d072255
📒 Files selected for processing (22)
common/constants.gocontroller/misc.gocontroller/usedata.gomodel/option.gomodel/usedata.goweb/src/components/dashboard/ChartsPanel.jsxweb/src/components/dashboard/index.jsxweb/src/components/dashboard/modals/SearchModal.jsxweb/src/components/settings/DashboardSetting.jsxweb/src/constants/dashboard.constants.jsweb/src/helpers/dashboard.jsxweb/src/helpers/data.jsweb/src/hooks/dashboard/useDashboardCharts.jsxweb/src/hooks/dashboard/useDashboardData.jsweb/src/i18n/locales/en.jsonweb/src/i18n/locales/fr.jsonweb/src/i18n/locales/ja.jsonweb/src/i18n/locales/ru.jsonweb/src/i18n/locales/vi.jsonweb/src/i18n/locales/zh-CN.jsonweb/src/i18n/locales/zh-TW.jsonweb/src/pages/Setting/Dashboard/SettingsDataDashboard.jsx
- ChartsPanel: replace bare Settings SVG trigger with Semi Button +
aria-label so keyboard and screen-reader users can open the chart
visibility popover
- Introduce CHART_TABS_NONE ('__none__') sentinel so admin can persist
"hide all charts"; '' keeps meaning "show all" for backward compat
- SettingsDataDashboard: encode empty vs all selection distinctly
- ChartsPanel: extract parseGlobalChartTabs helper and handle the new
sentinel in both visibleTabs and availableTabs
Review feedback addressedPushed 575f10b addressing @coderabbitai review:
Ready for another look 🙏 |
🧩 Analysis chainLet me check the updated code to verify the fixes. 🏁 Script executed: Length of output: 6819
✅ ChartsPanel a11y (Line 167–174) — Confirmed. The Popover trigger is now a proper Semi ✅ Empty-selection sentinel — Confirmed.
Triggering a fresh review pass now. ᓚᘏᗢ ✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
web/src/components/dashboard/ChartsPanel.jsx (1)
36-46: Add guard for missing or undefined specs to prevent silent rendering errors.
SPEC_MAPkeys currently align withALL_CHART_TABSkeys ('1'–'9'), so no drift issue exists today. However, the render block at lines 195–201 passesspec={specs[specKey]}without checking ifspecKeyorspecs[specKey]is defined. If a future tab is added toALL_CHART_TABSwithout a correspondingSPEC_MAPentry, or vice versa,VChartwill silently receiveundefined, leading to a blank or broken chart. A defensive guard ensures robustness:{visibleTabs.map((tab) => { if (activeChartTab !== tab.key) return null; const specKey = SPEC_MAP[tab.key]; + if (!specKey || !specs[specKey]) return null; return ( <VChart key={tab.key} spec={specs[specKey]} option={CHART_CONFIG} /> ); })}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/components/dashboard/ChartsPanel.jsx` around lines 36 - 46, Add a defensive guard where the component renders VChart so it never receives an undefined spec: before passing spec={specs[specKey]} (in the render that uses SPEC_MAP, ALL_CHART_TABS, specKey, specs and VChart) verify that specKey exists in SPEC_MAP and that specs[specKey] is defined; if missing, skip rendering that VChart or pass a safe fallback (e.g., an empty spec or a placeholder component) and log or warn so missing mappings are visible at runtime.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/dashboard/ChartsPanel.jsx`:
- Around line 103-107: handleUserTabsChange currently returns early when
checkedValues.length === 0 causing a silent no-op; instead, detect the empty
array and call the existing reset logic (reuse handleResetUserTabs semantics) so
the UI falls back to the global/default set and localStorage is updated.
Concretely, inside handleUserTabsChange (referencing setUserTabs and
STORAGE_KEYS.CHART_TABS_USER), replace the early return with a branch that calls
handleResetUserTabs() (or sets user tabs to the default array and writes that
value to localStorage) so the user sees the reset state rather than an
untickable checkbox.
- Around line 85-124: visibleTabs and availableTabs read
STORAGE_KEYS.CHART_TABS_GLOBAL directly inside useMemo but it isn't in their
dependency arrays, so updates to the admin global setting (localStorage) won't
recompute; fix by making the global setting reactive (e.g., create a small hook
that subscribes to window "storage" events or useSyncExternalStore to expose the
parsed global tabs) and replace the inline localStorage reads in visibleTabs and
availableTabs with that reactive value (use the hook to obtain parsedGlobalTabs
and include it in the useMemo dependencies), keeping parseGlobalChartTabs,
userTabs, isAdminUser, visibleTabs, and availableTabs as the identifying symbols
to modify.
---
Nitpick comments:
In `@web/src/components/dashboard/ChartsPanel.jsx`:
- Around line 36-46: Add a defensive guard where the component renders VChart so
it never receives an undefined spec: before passing spec={specs[specKey]} (in
the render that uses SPEC_MAP, ALL_CHART_TABS, specKey, specs and VChart) verify
that specKey exists in SPEC_MAP and that specs[specKey] is defined; if missing,
skip rendering that VChart or pass a safe fallback (e.g., an empty spec or a
placeholder component) and log or warn so missing mappings are visible at
runtime.
🪄 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: 3e2ddf2e-e7e1-474d-836d-284226e21881
📒 Files selected for processing (3)
web/src/components/dashboard/ChartsPanel.jsxweb/src/constants/dashboard.constants.jsweb/src/pages/Setting/Dashboard/SettingsDataDashboard.jsx
🚧 Files skipped from review as they are similar to previous changes (2)
- web/src/pages/Setting/Dashboard/SettingsDataDashboard.jsx
- web/src/constants/dashboard.constants.js
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4ee0930e-0dc8-4874-83e3-275f07704cb5
📒 Files selected for processing (7)
common/constants.gocontroller/misc.gomodel/option.goweb/classic/src/components/dashboard/ChartsPanel.jsxweb/classic/src/components/dashboard/index.jsxweb/classic/src/components/dashboard/modals/SearchModal.jsxweb/classic/src/components/settings/DashboardSetting.jsx
✅ Files skipped from review due to trivial changes (3)
- common/constants.go
- controller/misc.go
- web/classic/src/components/settings/DashboardSetting.jsx
…tion availableTabs was filtered by admin's globalTabs, which prevented users from selecting tabs outside the admin's allow-list. This contradicted the stated precedence (user preference > admin global > show all) and deadlocked the Popover when admin set __none__ (no checkboxes offered). Removing the globalTabs filter keeps admin's setting as a default for users who have not customized their preference, while allowing users to opt any permitted tab back on. adminOnly permission filter is retained. Flagged by CodeRabbit review on PR QuantumNous#4329.
51fdfc5 to
2b6f1df
Compare
Closes #4328
Summary
Enhance the data dashboard with model-dimension and user-dimension token usage
statistics, plus admin/user controllable chart tab visibility.
Changes
Backend
controller/usedata.go,model/usedata.go: addmodel_namefilter to dataendpoints; extend aggregation to include
token_usedmodel/option.go,common/constants.go: addDataDashboardChartTabsoptioncontroller/misc.go: expose the new option in status APIFrontend
components/dashboard/ChartsPanel.jsx: add Token Usage Distribution,User Token Ranking, and User Token Trend chart tabs
components/dashboard/modals/SearchModal.jsx: add model name filter inputhooks/dashboard/useDashboardCharts.jsx,useDashboardData.js:per-model/per-user aggregation logic
components/settings/DashboardSetting.jsx,Setting/Dashboard/SettingsDataDashboard.jsx: admin tab visibility configconstants/dashboard.constants.js,helpers/dashboard.jsx,helpers/data.js:shared definitions & helpers
i18n
Test plan
model_namefilter returns correctly scoped dataSummary by CodeRabbit
Release Notes
New Features