feat(ui): Merge Analytics pilot on the shared design system (U5 B2)#442
Conversation
Fourth B2 slice, and the first to use the BarList primitive: - libs/ui: AnalyticsDashboard gains an optional barLists prop (titled cards rendering a BarList distribution) alongside the chart cards — backward-compatible. New shared type UiBarListCard. - Electron: pure merge-analytics-ui mappers (shortenPath, formatDuration; buildMergeKpis/BarLists/Sections from MergeAnalytics + ConflictPattern, reusing analytics-ui's formatters; severity-toned conflict bars; the 0-1 rates become whole percents; 7 tests) + MergeAnalyticsPilotView over getMergeSummary + getConflictPatterns. Mounted as "Merge Analytics (new UI)". - i18n: analytics:mergePilot.* keys (en+fr), navigation.mergeAnalyticsNext. The merge report has no time series, so the KPI tiles carry no sparklines; the top conflict patterns render as a BarList ranked by occurrence count (bar tone follows conflict severity), with outcome / efficiency summary cards in the rail. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
📝 WalkthroughWalkthroughAdds a new merge analytics navigation view that fetches merge data through Electron IPC, maps it into dashboard cards and sections, renders conflict bar lists, and provides English/French localization with mapper tests. ChangesMerge analytics dashboard
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant MergeAnalyticsPilotView
participant ElectronIPC
participant merge_analytics_ui
participant AnalyticsDashboard
User->>MergeAnalyticsPilotView: open merge-analytics-next
MergeAnalyticsPilotView->>ElectronIPC: request merge summary and conflict patterns
ElectronIPC-->>MergeAnalyticsPilotView: return analytics data
MergeAnalyticsPilotView->>merge_analytics_ui: build dashboard view models
merge_analytics_ui-->>MergeAnalyticsPilotView: return KPIs, bar lists, and sections
MergeAnalyticsPilotView->>AnalyticsDashboard: render localized dashboard
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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: 1
🤖 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 `@apps/frontend/src/renderer/lib/merge-analytics-ui.ts`:
- Around line 103-110: Update formatDuration and its callers so duration strings
are produced through the app’s react-i18next-backed formatter or localized
templates exposed via MergeSectionLabels, including the zero/invalid, seconds,
and minutes-and-seconds cases. Remove hardcoded user-facing “m” and “s” text,
pass the localized formatter from the view, and extend the related tests to
verify the French output.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c18372d0-d070-4bc0-9b22-821de938acc7
📒 Files selected for processing (13)
apps/frontend/src/renderer/App.tsxapps/frontend/src/renderer/__tests__/merge-analytics-ui.test.tsapps/frontend/src/renderer/components/MergeAnalyticsPilotView.tsxapps/frontend/src/renderer/components/Sidebar.tsxapps/frontend/src/renderer/lib/merge-analytics-ui.tsapps/frontend/src/shared/i18n/locales/en/analytics.jsonapps/frontend/src/shared/i18n/locales/en/navigation.jsonapps/frontend/src/shared/i18n/locales/fr/analytics.jsonapps/frontend/src/shared/i18n/locales/fr/navigation.jsonlibs/ui/src/client/types.tslibs/ui/src/index.tslibs/ui/src/screens/AnalyticsDashboard.stories.tsxlibs/ui/src/screens/AnalyticsDashboard.tsx
| /** Seconds → "45s" or "2m 05s". */ | ||
| export function formatDuration(seconds: number): string { | ||
| if (!Number.isFinite(seconds) || seconds < 0) return '0s'; | ||
| const whole = Math.round(seconds); | ||
| if (whole < 60) return `${whole}s`; | ||
| const minutes = Math.floor(whole / 60); | ||
| const rest = whole % 60; | ||
| return `${minutes}m ${String(rest).padStart(2, '0')}s`; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Localize duration display values.
formatDuration emits user-facing "0s", "m", and "s" strings, bypassing the app’s i18n layer. Pass an i18n-backed duration formatter from the view (or localized duration templates through MergeSectionLabels) and update these tests to cover the French result.
Proposed direction
export interface MergeSectionLabels {
+ formatDuration: (seconds: number) => string;
// ...
}
- value: formatDuration(analytics.average_duration_seconds),
+ value: labels.formatDuration(analytics.average_duration_seconds),As per coding guidelines, “All user-facing text must use i18n translation keys from react-i18next with format namespace:section.key.”
🤖 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 `@apps/frontend/src/renderer/lib/merge-analytics-ui.ts` around lines 103 - 110,
Update formatDuration and its callers so duration strings are produced through
the app’s react-i18next-backed formatter or localized templates exposed via
MergeSectionLabels, including the zero/invalid, seconds, and minutes-and-seconds
cases. Remove hardcoded user-facing “m” and “s” text, pass the localized
formatter from the view, and extend the related tests to verify the French
output.
Source: Coding guidelines
|



Summary
Fourth B2 slice — the first to compose the
BarListprimitive (#441). Its conflict-pattern distribution is exactly the histogram pattern the primitive was built for.libs/ui
barListsprop — titled cards each rendering aBarListdistribution, in the main column alongside the chart cards. Backward-compatible (existing Analytics/Productivity screens unaffected).UiBarListCard.Electron
merge-analytics-uimappers:shortenPath(compact file labels),formatDuration;buildMergeKpis/buildMergeBarLists/buildMergeSectionsfromMergeAnalytics+ConflictPattern, reusinganalytics-ui's formatters. Conflict-bar tone follows the pattern severity (high/critical → red, medium → amber, low → blue); 0–1 rates become whole percents. 7 tests.MergeAnalyticsPilotViewovergetMergeSummary+getConflictPatterns, mounted as "Merge Analytics (new UI)" beside the legacy view (export flow stays there).i18n
analytics:mergePilot.*(en+fr),navigation:items.mergeAnalyticsNext.Scope
The merge report has no time series, so the KPI tiles carry no sparklines. The top conflict files render as a
BarListranked by occurrence count; outcome/efficiency figures fill the summary rail.Verification
libs/ui+ Electron tsc clean; i18n parity confirmed (20 keys en+fr); no nested ternaries. Storybook rebuilt and the newAnalyticsDashboardWithBarListstory verified against the mockup in light + dark (severity-toned conflict bars beside KPIs + rail).Next in B2
Model Usage (line/sparkline + a per-model
BarList) closes the batch.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests