Overhaul battery panel: responsive layout, configurable options, enterprise-level UI

- Responsive layout adapts to any panel size (mobile to widescreen)
  - Auto-switches between column/row layout based on dimensions
  - Gracefully degrades in tiny panels (hides stats, keeps battery)
  - Font sizes scale dynamically to available space

- New configurable options via Grafana panel editor:
  - Colours category: low/mid/high battery colours
  - Thresholds category: configurable low/high % boundaries (was hardcoded 30/70)
  - Appearance category: gradient fill, orientation (vertical/horizontal),
    charging animation, border width
  - Display category: individual show/hide toggles for percentage, rate,
    low/high stats, charging status
  - Data category: decimal places, regression toggle

- Fixed bugs:
  - Gradient ID now unique per panel instance (fixes multi-panel dashboards)
  - Battery fill uses clipPath so it respects rounded corners
  - Proper 'No data' empty state

- Horizontal battery orientation for wide/short panels
- Pulse animation when charging (configurable)
- Status badge with themed colours (charging/discharging/stable)
- Moved options interface to shared types.ts
- Updated stale e2e tests to match current component

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Andy Dixon
2026-04-24 13:06:47 +01:00
co-authored by Copilot
parent d971e218e4
commit 942a390248
5 changed files with 17284 additions and 258 deletions
+26 -5
View File
@@ -1,7 +1,28 @@
type SeriesSize = 'sm' | 'md' | 'lg';
export type BatteryOrientation = 'vertical' | 'horizontal';
export interface SimpleOptions {
text: string;
showSeriesCount: boolean;
seriesCountSize: SeriesSize;
export interface ChargeVizOptions {
// Colours
lowColour: string;
midColour: string;
highColour: string;
// Thresholds
lowThreshold: number;
highThreshold: number;
// Appearance
gradientFill: boolean;
orientation: BatteryOrientation;
chargingAnimation: boolean;
borderWidth: number;
// Data display
decimalPlaces: number;
useRegressionForRate: boolean;
// Visibility toggles
showPercentage: boolean;
showRate: boolean;
showLowHigh: boolean;
showStatus: boolean;
}