feat: add D3 gauge components with dashboard table, card, and detail … - #35
Conversation
…views Replace horizontal metric bars with D3 270° donut arc gauges across the frontend. - New Gauge component (src/components/Gauge.jsx) renders a configurable 270° donut arc with percentage display, label, custom size/color, and value clamping. - Dashboard UPS table now shows compact battery/load gauges per device, fetched via a second useEffect for per-UPS detail data. - UpsCard replaces horizontal bar metrics with compact 76px gauges. - UpsDetail displays large 100px gauges in a metrics bar for charge and load, with those fields filtered out of the grouped grid sections. - CSS additions: gauge wrapper/container/value/label, dash-ups-table grid layout, detail-metrics bar with gradient border, card-metrics-row-gauges. - Tests cover Gauge (10 cases), Dashboard (7 cases), UpsCard (7 cases), and UpsDetail (6 cases). d3 added as a dependency.
|
Warning Review limit reached
More reviews will be available in 43 minutes and 34 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR introduces a new SVG gauge visualization component and integrates it into the UPS monitoring dashboard. The ChangesGauge Component & Integration
Sequence Diagram(s)sequenceDiagram
participant Dashboard
participant API
participant Gauge
Dashboard->>API: fetch API.upsDetail(name) for each UPS
API-->>Dashboard: return detail with battery.charge, ups.load
Dashboard->>Dashboard: store in details state (name-keyed)
Dashboard->>Gauge: render Gauge with charge/load values
Gauge-->>Dashboard: display arc meter and percentage
flowchart TD
Detail["detail object from API"]
Extract["Extract: charge, load, runtime, voltage"]
MetricsSection["detail-metrics section"]
GridVars["detail-grid variables"]
Detail --> Extract
Extract --> MetricsSection
Extract --> GridVars
MetricsSection --> GaugeCharge["Gauge: battery.charge"]
MetricsSection --> GaugeLoad["Gauge: ups.load"]
MetricsSection --> TextMetrics["Text: runtime, voltage"]
GridVars --> FilteredGrid["Filter out charge/load, render rest"]
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)
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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/frontend/src/__tests__/components/Gauge.test.jsx`:
- Around line 33-36: Add two boundary tests to Gauge.test.jsx to assert the
normalization contract: one that renders Gauge with value={-10} and max={100}
(expecting to find "0%") and another that renders Gauge with a non-positive max
(e.g., value={50} max={0} and also try max={-10}) expecting "0%". Use the same
pattern as the existing "clamps value to max" test (render(<Gauge ... />) and
expect(screen.getByText('0%')).toBeInTheDocument()) so the Gauge component's
negative-value and non-positive-max behavior is explicitly covered.
In `@src/frontend/src/components/Gauge.jsx`:
- Line 8: Clamp and sanitize the percentage calculation in Gauge.jsx: validate
that max is a finite positive number and that value is finite, then compute pct
= Math.min(Math.max(value / max, 0), 1) (or set pct = 0 when max is invalid) so
pct is always in [0,1] and not NaN/Infinity; update usages of pct (text
rendering and arc geometry) to rely on this sanitized value (refer to the pct
variable and the value/max inputs in the render function that builds the arc and
label).
In `@src/frontend/src/components/UpsDetail.jsx`:
- Around line 175-200: Duplicate color-threshold logic in UpsDetail and UpsCard
should be extracted to shared utility functions; create two functions (e.g.,
getBatteryChargeColor(charge) and getLoadColor(load)) that encapsulate the
existing threshold logic (charge: <=20 red, <=50 orange, else green; load: >=80
red, >=60 orange, else accent), add them to a new module (e.g.,
utils/metrics.js), then replace the inline ternaries in the UpsDetail component
(inside the Gauge props for Battery and Load) and the similar logic in UpsCard
to import and call these utilities so both components use the single source of
truth.
🪄 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
Run ID: 04b735b1-58a0-470c-a43e-07dd2c4bc9b2
⛔ Files ignored due to path filters (1)
src/frontend/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (10)
src/frontend/package.jsonsrc/frontend/src/__tests__/components/Dashboard.test.jsxsrc/frontend/src/__tests__/components/Gauge.test.jsxsrc/frontend/src/__tests__/components/UpsCard.test.jsxsrc/frontend/src/__tests__/components/UpsDetail.test.jsxsrc/frontend/src/components/Dashboard.jsxsrc/frontend/src/components/Gauge.jsxsrc/frontend/src/components/UpsCard.jsxsrc/frontend/src/components/UpsDetail.jsxsrc/frontend/src/styles/components.css
Guard Gauge.jsx against NaN, Infinity, and negative percentages by validating that max is positive and value is finite before computing pct, defaulting to 0 otherwise. This prevents "-10%" text rendering and broken arc geometry when upstream data is malformed. Extract duplicate color-threshold logic from UpsCard and UpsDetail into shared getBatteryChargeColor() and getLoadColor() in utils/metrics.js so both components use a single source of truth for the charge and load color mapping. Add boundary tests for negative values and non-positive max to codify the normalization contract.
…views
Replace horizontal metric bars with D3 270° donut arc gauges across the frontend.
Summary by CodeRabbit
New Features
Tests
Style
Chores