feat: redesign dashboard with Fluent KPI tiles, connection strip, and devices column

- Replace LCD-style readings with a 3×2 KPI tile grid (Fluent card surfaces, 52pt values)
- Add persistent top connection strip with horizontal chips + pump name badge
- Add elapsed test timer (DispatcherTimer, mm:ss) to Test Summary card
- Restyle Test Summary and Active Alarms with Fluent brushes/iconography
- Add Devices column (CAN / K-Line / Bench tiles) between KPI grid and test/alarms
  - Enumerates attached PCAN USB channels via PCAN_ATTACHED_CHANNELS API
  - Enumerates FTDI K-Line adapters via existing FtdiInterface helpers
  - Click to connect/disconnect; confirmation dialog when session active or test running
  - Hover tint: blue = will connect, red = will disconnect; Bench row is read-only stub
- Extend ICanService with SelectedChannel + EnumerateAttachedChannels()
- Expose IKwpService.ConnectedPort for active session device tracking
- Add DeviceRow button style with MultiDataTrigger hover colour logic
- Add 30+ new localization keys (ES + EN) for KPI labels, devices, confirmations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-19 22:25:00 +02:00
parent 0280a2fad1
commit 197e9d1775
26 changed files with 1638 additions and 515 deletions

View File

@@ -42,6 +42,40 @@
<sys:String x:Key="Dashboard.Action.Stop">Stop</sys:String>
<sys:String x:Key="Dashboard.Action.EmergencyStop">EMERGENCY STOP</sys:String>
<!-- ── Dashboard KPI tile labels ──────────────────────────────────────── -->
<sys:String x:Key="Dashboard.Kpi.Rpm">Bench RPM</sys:String>
<sys:String x:Key="Dashboard.Kpi.Qdelivery">Q delivery</sys:String>
<sys:String x:Key="Dashboard.Kpi.P1">Pressure P1</sys:String>
<sys:String x:Key="Dashboard.Kpi.P2">Pressure P2</sys:String>
<sys:String x:Key="Dashboard.Kpi.Tin">Oil in T</sys:String>
<sys:String x:Key="Dashboard.Kpi.Tout">Oil out T</sys:String>
<sys:String x:Key="Dashboard.Kpi.Unit.Rpm">rpm</sys:String>
<sys:String x:Key="Dashboard.Kpi.Unit.CcS">cc/s</sys:String>
<sys:String x:Key="Dashboard.Kpi.Unit.Bar">bar</sys:String>
<sys:String x:Key="Dashboard.Kpi.Unit.Celsius">°C</sys:String>
<!-- Dashboard test summary extras -->
<sys:String x:Key="Dashboard.TestSummary.Elapsed">Elapsed:</sys:String>
<!-- Dashboard connection chip extras -->
<sys:String x:Key="Dashboard.Conn.Pump.Label">Pump:</sys:String>
<sys:String x:Key="Dashboard.Conn.NoPump">No pump</sys:String>
<!-- ── Dashboard Devices column ─────────────────────────────────────── -->
<sys:String x:Key="Dashboard.Devices">Devices</sys:String>
<sys:String x:Key="Dashboard.Devices.Can">CAN</sys:String>
<sys:String x:Key="Dashboard.Devices.Kline">K-Line</sys:String>
<sys:String x:Key="Dashboard.Devices.Bench">Bench</sys:String>
<sys:String x:Key="Dashboard.Devices.Refresh">Refresh</sys:String>
<sys:String x:Key="Dashboard.Devices.State.Idle">Available</sys:String>
<sys:String x:Key="Dashboard.Devices.State.Connected">Connected</sys:String>
<sys:String x:Key="Dashboard.Devices.State.Active">Session active</sys:String>
<sys:String x:Key="Dashboard.Devices.State.Failed">Error</sys:String>
<sys:String x:Key="Dashboard.Devices.None">No devices found</sys:String>
<sys:String x:Key="Dashboard.Devices.BenchRow">Bench controller</sys:String>
<!-- Confirmation dialogs -->
<sys:String x:Key="Devices.Confirm.Title">Confirm device change</sys:String>
<sys:String x:Key="Devices.Confirm.Body.Active">The {0} session is active. Disconnect?</sys:String>
<sys:String x:Key="Devices.Confirm.Body.TestRunning">A test is running. Changing device state may abort it. Continue?</sys:String>
<!-- ── Status bar / connection indicators ───────────────────────────── -->
<sys:String x:Key="Status.Label">Status:</sys:String>
<sys:String x:Key="Status.Can">CAN</sys:String>