feat: add animated totals/averages to dashboard chart card headers - #3499
Conversation
📝 WalkthroughWalkthroughThis PR refactors the dashboard chart system by updating the ChangesDashboard Chart Component and Metric Refactoring
🎯 3 (Moderate) | ⏱️ ~22 minutes
🚥 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 docstrings
🧪 Generate unit tests (beta)
Comment |
This stack of pull requests is managed by Graphite. Learn more about stacking. |
b57b48b to
9e677b6
Compare
9e677b6 to
cb00051
Compare
Confidence Score: 4/5Safe to merge; changes are confined to dashboard UI presentation logic with no backend or data-fetching impact. The aggregate and weighted-average computations are correct against the TypeScript types, filter-aware cost totals match the No files require special attention; Important Files Changed
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
ui/app/workspace/dashboard/components/overviewTab.tsx (1)
228-279: 💤 Low valueConsider extracting legend rendering into separate components.
The Cost and Model Usage legends contain 4 levels of nested conditionals, which makes the JSX harder to scan. Consider extracting
CostLegendandModelUsageLegendcomponents to improve readability and testability.Example:
<CostLegend selectedModel={costModel} models={costModels} />This would move the conditional logic into dedicated, testable components.
Also applies to: 303-354
🤖 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 `@ui/app/workspace/dashboard/components/overviewTab.tsx` around lines 228 - 279, The JSX in the legend block is deeply nested and hard to read; extract the conditional rendering into a dedicated component (e.g., CostLegend) and do the same for the model-usage legend (e.g., ModelUsageLegend). Move the current logic that branches on costModel === "all", costModels, the Tooltip/TooltipTrigger/TooltipContent structure, getModelColor usage, and the CHART_HEADER_LEGEND_CLASS wrapper into the new CostLegend component which accepts props (selectedModel: costModel, models: costModels, getModelColor) and returns the same markup; then replace the inline legend JSX in overviewTab.tsx with <CostLegend .../> (and similarly extract ModelUsageLegend for the other block), keeping all keys and aria/test ids (data-testid="cost-legend-trigger", "cost-legend-more-trigger", "cost-legend-single-trigger") intact so behavior and tests remain unchanged.
🤖 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.
Nitpick comments:
In `@ui/app/workspace/dashboard/components/overviewTab.tsx`:
- Around line 228-279: The JSX in the legend block is deeply nested and hard to
read; extract the conditional rendering into a dedicated component (e.g.,
CostLegend) and do the same for the model-usage legend (e.g., ModelUsageLegend).
Move the current logic that branches on costModel === "all", costModels, the
Tooltip/TooltipTrigger/TooltipContent structure, getModelColor usage, and the
CHART_HEADER_LEGEND_CLASS wrapper into the new CostLegend component which
accepts props (selectedModel: costModel, models: costModels, getModelColor) and
returns the same markup; then replace the inline legend JSX in overviewTab.tsx
with <CostLegend .../> (and similarly extract ModelUsageLegend for the other
block), keeping all keys and aria/test ids (data-testid="cost-legend-trigger",
"cost-legend-more-trigger", "cost-legend-single-trigger") intact so behavior and
tests remain unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 18d3621f-c443-4f18-b61f-c0fe7edc69bb
📒 Files selected for processing (9)
ui/app/workspace/dashboard/components/charts/chartCard.tsxui/app/workspace/dashboard/components/charts/logVolumeChart.tsxui/app/workspace/dashboard/components/charts/mcpTopToolsChart.tsxui/app/workspace/dashboard/components/charts/mcpVolumeChart.tsxui/app/workspace/dashboard/components/charts/modelUsageChart.tsxui/app/workspace/dashboard/components/mcpTab.tsxui/app/workspace/dashboard/components/modelRankingsTab.tsxui/app/workspace/dashboard/components/overviewTab.tsxui/app/workspace/dashboard/components/providerUsageTab.tsx
Merge activity
|
…3499) ## Summary Adds aggregate totals and a weighted average latency metric to each dashboard chart card header, giving users an at-a-glance summary of the data currently displayed in each chart. ## Changes - Replaced the single `headerActions` prop on `ChartCard` with separate `controls`, `legend`, and `total`/`totalLabel` props, and extracted a `Header` sub-component and `TotalChip` sub-component to render them in a structured layout (title row → total + controls row → legend row). - Each dashboard tab (Overview, MCP, Provider Usage, Model Rankings) now computes its own aggregate value via `useMemo`: - Request Volume, Token Usage, Model Usage, MCP Tool Calls, MCP Top Tools, Provider Token Usage → sum of counts/tokens across all buckets. - Cost (MCP, Overview, Provider) → sum of `total_cost` across buckets, respecting the active model/provider filter. - Latency (Overview, Provider) → request-count-weighted average of `avg_latency` across buckets. - Totals are rendered using `NumberFlow` with `COMPACT_NUMBER_FORMAT` for counts, currency formatting for costs, and a fixed two-decimal `ms` suffix for latency averages. - Y-axis tick formatters across `logVolumeChart`, `mcpVolumeChart`, `mcpTopToolsChart`, and `modelUsageChart` switched from `v.toLocaleString()` to the shared `formatTokens` utility, and axis widths were normalised to 44px. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test ```sh cd ui pnpm i pnpm build ``` 1. Open the dashboard and navigate to the Overview, MCP, Provider Usage, and Model Rankings tabs. 2. Verify each chart card header shows a labelled total (e.g. "Total 1.2k", "Total $0.04", "Avg 312.50ms"). 3. Change the model or provider filter on Cost / Model Usage / Provider charts and confirm the displayed total updates to reflect the filtered data. 4. Toggle between bar and area chart types and confirm the total remains consistent. 5. Verify the loading skeleton state still renders correctly without the total chip. ## Screenshots/Recordings [Screen Recording 2026-05-14 at 6.52.34 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.com/user-attachments/thumbnails/24c91fe3-6582-42b0-8d98-1aa46f80607c.mov" />](https://app.graphite.com/user-attachments/video/24c91fe3-6582-42b0-8d98-1aa46f80607c.mov) ## Breaking changes - [x] No The `headerActions` prop on `ChartCard` has been removed and replaced with `controls`, `legend`, `total`, and `totalLabel`. Any consumers outside this PR that pass `headerActions` will need to be updated. ## Related issues ## Security considerations None. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…3499) ## Summary Adds aggregate totals and a weighted average latency metric to each dashboard chart card header, giving users an at-a-glance summary of the data currently displayed in each chart. ## Changes - Replaced the single `headerActions` prop on `ChartCard` with separate `controls`, `legend`, and `total`/`totalLabel` props, and extracted a `Header` sub-component and `TotalChip` sub-component to render them in a structured layout (title row → total + controls row → legend row). - Each dashboard tab (Overview, MCP, Provider Usage, Model Rankings) now computes its own aggregate value via `useMemo`: - Request Volume, Token Usage, Model Usage, MCP Tool Calls, MCP Top Tools, Provider Token Usage → sum of counts/tokens across all buckets. - Cost (MCP, Overview, Provider) → sum of `total_cost` across buckets, respecting the active model/provider filter. - Latency (Overview, Provider) → request-count-weighted average of `avg_latency` across buckets. - Totals are rendered using `NumberFlow` with `COMPACT_NUMBER_FORMAT` for counts, currency formatting for costs, and a fixed two-decimal `ms` suffix for latency averages. - Y-axis tick formatters across `logVolumeChart`, `mcpVolumeChart`, `mcpTopToolsChart`, and `modelUsageChart` switched from `v.toLocaleString()` to the shared `formatTokens` utility, and axis widths were normalised to 44px. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test ```sh cd ui pnpm i pnpm build ``` 1. Open the dashboard and navigate to the Overview, MCP, Provider Usage, and Model Rankings tabs. 2. Verify each chart card header shows a labelled total (e.g. "Total 1.2k", "Total $0.04", "Avg 312.50ms"). 3. Change the model or provider filter on Cost / Model Usage / Provider charts and confirm the displayed total updates to reflect the filtered data. 4. Toggle between bar and area chart types and confirm the total remains consistent. 5. Verify the loading skeleton state still renders correctly without the total chip. ## Screenshots/Recordings [Screen Recording 2026-05-14 at 6.52.34 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.com/user-attachments/thumbnails/24c91fe3-6582-42b0-8d98-1aa46f80607c.mov" />](https://app.graphite.com/user-attachments/video/24c91fe3-6582-42b0-8d98-1aa46f80607c.mov) ## Breaking changes - [x] No The `headerActions` prop on `ChartCard` has been removed and replaced with `controls`, `legend`, `total`, and `totalLabel`. Any consumers outside this PR that pass `headerActions` will need to be updated. ## Related issues ## Security considerations None. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…3499) ## Summary Adds aggregate totals and a weighted average latency metric to each dashboard chart card header, giving users an at-a-glance summary of the data currently displayed in each chart. ## Changes - Replaced the single `headerActions` prop on `ChartCard` with separate `controls`, `legend`, and `total`/`totalLabel` props, and extracted a `Header` sub-component and `TotalChip` sub-component to render them in a structured layout (title row → total + controls row → legend row). - Each dashboard tab (Overview, MCP, Provider Usage, Model Rankings) now computes its own aggregate value via `useMemo`: - Request Volume, Token Usage, Model Usage, MCP Tool Calls, MCP Top Tools, Provider Token Usage → sum of counts/tokens across all buckets. - Cost (MCP, Overview, Provider) → sum of `total_cost` across buckets, respecting the active model/provider filter. - Latency (Overview, Provider) → request-count-weighted average of `avg_latency` across buckets. - Totals are rendered using `NumberFlow` with `COMPACT_NUMBER_FORMAT` for counts, currency formatting for costs, and a fixed two-decimal `ms` suffix for latency averages. - Y-axis tick formatters across `logVolumeChart`, `mcpVolumeChart`, `mcpTopToolsChart`, and `modelUsageChart` switched from `v.toLocaleString()` to the shared `formatTokens` utility, and axis widths were normalised to 44px. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [x] UI (React) - [ ] Docs ## How to test ```sh cd ui pnpm i pnpm build ``` 1. Open the dashboard and navigate to the Overview, MCP, Provider Usage, and Model Rankings tabs. 2. Verify each chart card header shows a labelled total (e.g. "Total 1.2k", "Total $0.04", "Avg 312.50ms"). 3. Change the model or provider filter on Cost / Model Usage / Provider charts and confirm the displayed total updates to reflect the filtered data. 4. Toggle between bar and area chart types and confirm the total remains consistent. 5. Verify the loading skeleton state still renders correctly without the total chip. ## Screenshots/Recordings [Screen Recording 2026-05-14 at 6.52.34 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.com/user-attachments/thumbnails/24c91fe3-6582-42b0-8d98-1aa46f80607c.mov" />](https://app.graphite.com/user-attachments/video/24c91fe3-6582-42b0-8d98-1aa46f80607c.mov) ## Breaking changes - [x] No The `headerActions` prop on `ChartCard` has been removed and replaced with `controls`, `legend`, `total`, and `totalLabel`. Any consumers outside this PR that pass `headerActions` will need to be updated. ## Related issues ## Security considerations None. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable

Summary
Adds aggregate totals and a weighted average latency metric to each dashboard chart card header, giving users an at-a-glance summary of the data currently displayed in each chart.
Changes
headerActionsprop onChartCardwith separatecontrols,legend, andtotal/totalLabelprops, and extracted aHeadersub-component andTotalChipsub-component to render them in a structured layout (title row → total + controls row → legend row).useMemo:total_costacross buckets, respecting the active model/provider filter.avg_latencyacross buckets.NumberFlowwithCOMPACT_NUMBER_FORMATfor counts, currency formatting for costs, and a fixed two-decimalmssuffix for latency averages.logVolumeChart,mcpVolumeChart,mcpTopToolsChart, andmodelUsageChartswitched fromv.toLocaleString()to the sharedformatTokensutility, and axis widths were normalised to 44px.Type of change
Affected areas
How to test
cd ui pnpm i pnpm buildScreenshots/Recordings
Screen Recording 2026-05-14 at 6.52.34 PM.mov (uploaded via Graphite)
Breaking changes
The
headerActionsprop onChartCardhas been removed and replaced withcontrols,legend,total, andtotalLabel. Any consumers outside this PR that passheaderActionswill need to be updated.Related issues
Security considerations
None.
Checklist
docs/contributing/README.mdand followed the guidelines