feat: redesign Pump page with Fluent card layout, bottom snackbar, and RPM chart

- Replace sub-nav + HiddenTabsTabControl with 3-column Fluent card layout:
  PumpCommandsCard (vertical ME/FBKW/PreIn sliders) + DfiCalibrationCard /
  PumpLiveDataCard (KPI tiles + RPM rolling chart + redesigned status bytes) /
  PumpIdentificationCard + DtcCard
- Add PumpTopStripView: pump selector, model badge, CAN + K-Line chips
- Move immobilizer unlock to MainWindow bottom snackbar (UnlockSnackbarView):
  auto-close on success after 3 s, persist on failure with manual Dismiss
- Redesign StatusDisplayView to 2×8 rounded 28px tiles with bit index + tooltip
- Add NullToVisibilityConverter; add SnackbarShell, PumpCard, and related styles
- Delete obsolete views: UnlockProgressDialog, UnlockPanelView,
  PumpIdentificationPanelView, PumpLiveDataView, DfiManageView,
  DtcListView, PumpControlView
- PumpPageViewModel: remove PumpSubPage enum, add RpmChart wired to Root.PumpRpm

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 14:03:47 +02:00
parent 197e9d1775
commit 70be693116
37 changed files with 1356 additions and 1317 deletions

View File

@@ -166,6 +166,31 @@
<sys:String x:Key="Pump.Rpm">RPM</sys:String>
<sys:String x:Key="Pump.TEin">T-ein</sys:String>
<sys:String x:Key="Pump.UnitRpm">1/min</sys:String>
<sys:String x:Key="Pump.UnitCelsius">°C</sys:String>
<sys:String x:Key="Pump.UnitUs">µs</sys:String>
<sys:String x:Key="Pump.Commands.Title">Pump Commands</sys:String>
<sys:String x:Key="Pump.Commands.Me">ME</sys:String>
<sys:String x:Key="Pump.Commands.Fbkw">FBKW</sys:String>
<sys:String x:Key="Pump.Commands.PreIn">Pre-inj</sys:String>
<sys:String x:Key="Pump.LiveData.Title">Live Data</sys:String>
<sys:String x:Key="Pump.LiveData.RPM">Pump RPM</sys:String>
<sys:String x:Key="Pump.LiveData.THyb">T-hyb</sys:String>
<sys:String x:Key="Pump.LiveData.TEin">T-ein</sys:String>
<sys:String x:Key="Pump.LiveData.Me">ME</sys:String>
<sys:String x:Key="Pump.LiveData.Fbkw">FBKW</sys:String>
<sys:String x:Key="Pump.LiveData.RpmChart">RPM trend</sys:String>
<sys:String x:Key="Pump.Status.Active">Active</sys:String>
<sys:String x:Key="Pump.Dfi.Title">Idling Calibration</sys:String>
<sys:String x:Key="Pump.Dfi.Version">Version</sys:String>
<sys:String x:Key="Pump.Dfi.Current">Current DFI</sys:String>
<sys:String x:Key="Pump.Dtcs.Title">Fault Codes</sys:String>
<sys:String x:Key="Pump.Identification.Title">Identification</sys:String>
<sys:String x:Key="Pump.TopStrip.Brand">Brand</sys:String>
<sys:String x:Key="Pump.TopStrip.NoPump">No pump selected</sys:String>
<sys:String x:Key="Pump.TopStrip.Can">CAN</sys:String>
<sys:String x:Key="Pump.TopStrip.KLine">K-Line</sys:String>
<sys:String x:Key="Pump.NoPumpBanner">No pump selected — select a pump to enable diagnostics.</sys:String>
<sys:String x:Key="Pump.FastUnlock">Fast unlock attempt...</sys:String>
<!-- ── Pump identification ──────────────────────────────────────────── -->
<sys:String x:Key="PumpId.Label">Pump:</sys:String>
@@ -323,6 +348,7 @@
<sys:String x:Key="Common.No">No</sys:String>
<sys:String x:Key="Common.Warning">WARNING</sys:String>
<sys:String x:Key="Common.Disabled">disabled</sys:String>
<sys:String x:Key="Common.Dismiss">Dismiss</sys:String>
<!-- ── Dialog: Report ───────────────────────────────────────────────── -->
<sys:String x:Key="Dialog.Report.Title">Generate Report</sys:String>

View File

@@ -166,6 +166,31 @@
<sys:String x:Key="Pump.Rpm">RPM</sys:String>
<sys:String x:Key="Pump.TEin">T-ein</sys:String>
<sys:String x:Key="Pump.UnitRpm">1/min</sys:String>
<sys:String x:Key="Pump.UnitCelsius">°C</sys:String>
<sys:String x:Key="Pump.UnitUs">µs</sys:String>
<sys:String x:Key="Pump.Commands.Title">Pump Commands</sys:String>
<sys:String x:Key="Pump.Commands.Me">ME</sys:String>
<sys:String x:Key="Pump.Commands.Fbkw">FBKW</sys:String>
<sys:String x:Key="Pump.Commands.PreIn">Pre-inj</sys:String>
<sys:String x:Key="Pump.LiveData.Title">Live Data</sys:String>
<sys:String x:Key="Pump.LiveData.RPM">RPM Bomba</sys:String>
<sys:String x:Key="Pump.LiveData.THyb">T-hyb</sys:String>
<sys:String x:Key="Pump.LiveData.TEin">T-ein</sys:String>
<sys:String x:Key="Pump.LiveData.Me">ME</sys:String>
<sys:String x:Key="Pump.LiveData.Fbkw">FBKW</sys:String>
<sys:String x:Key="Pump.LiveData.RpmChart">Tendencia RPM</sys:String>
<sys:String x:Key="Pump.Status.Active">Activo</sys:String>
<sys:String x:Key="Pump.Dfi.Title">Calibración Ralentí</sys:String>
<sys:String x:Key="Pump.Dfi.Version">Versión</sys:String>
<sys:String x:Key="Pump.Dfi.Current">DFI Actual</sys:String>
<sys:String x:Key="Pump.Dtcs.Title">Códigos de Falla</sys:String>
<sys:String x:Key="Pump.Identification.Title">Identificación</sys:String>
<sys:String x:Key="Pump.TopStrip.Brand">Marca</sys:String>
<sys:String x:Key="Pump.TopStrip.NoPump">Sin bomba seleccionada</sys:String>
<sys:String x:Key="Pump.TopStrip.Can">CAN</sys:String>
<sys:String x:Key="Pump.TopStrip.KLine">K-Line</sys:String>
<sys:String x:Key="Pump.NoPumpBanner">Sin bomba seleccionada — seleccione una bomba para habilitar el diagnóstico.</sys:String>
<sys:String x:Key="Pump.FastUnlock">Intento de desbloqueo rápido...</sys:String>
<!-- ── Pump identification ──────────────────────────────────────────── -->
<sys:String x:Key="PumpId.Label">Bomba:</sys:String>
@@ -323,6 +348,7 @@
<sys:String x:Key="Common.No">No</sys:String>
<sys:String x:Key="Common.Warning">ADVERTENCIA</sys:String>
<sys:String x:Key="Common.Disabled">deshabilitado</sys:String>
<sys:String x:Key="Common.Dismiss">Cerrar</sys:String>
<!-- ── Dialog: Report ───────────────────────────────────────────────── -->
<sys:String x:Key="Dialog.Report.Title">Generar Informe</sys:String>

View File

@@ -1,9 +1,13 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:HC_APTBS.Converters">
<!-- Boolean → Visibility converter (shared across views) -->
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
<!-- Null → Collapsed, non-null → Visible -->
<conv:NullToVisibilityConverter x:Key="NullToVis"/>
<!-- LCD blue gradient border -->
<Style x:Key="LcdBlue" TargetType="Border">
<Setter Property="BorderBrush" Value="Black"/>
@@ -160,6 +164,62 @@
<Setter Property="Margin" Value="6,0,4,0"/>
</Style>
<!-- ── Pump page card chrome (same Fluent look as Dashboard inline cards) ── -->
<Style x:Key="PumpCard" TargetType="Border">
<Setter Property="Background" Value="{DynamicResource CardBackgroundFillColorDefaultBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="8"/>
<Setter Property="Padding" Value="16"/>
<Setter Property="Margin" Value="4"/>
</Style>
<Style x:Key="PumpCardHeader" TargetType="TextBlock">
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Foreground" Value="{DynamicResource TextFillColorPrimaryBrush}"/>
<Setter Property="Margin" Value="0,0,0,10"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<!-- Small label beneath a pump slider (parameter name, unit, range limit) -->
<Style x:Key="PumpCommandLabel" TargetType="TextBlock">
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="Foreground" Value="{DynamicResource TextFillColorSecondaryBrush}"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="TextAlignment" Value="Center"/>
</Style>
<!-- Current-value readout beneath a pump slider -->
<Style x:Key="PumpCommandValue" TargetType="TextBox">
<Setter Property="FontFamily" Value="Consolas"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Foreground" Value="{DynamicResource AccentTextFillColorPrimaryBrush}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="Padding" Value="4,2"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="30"/>
</Style>
<!-- Snackbar bottom-overlay shell -->
<Style x:Key="SnackbarShell" TargetType="Border">
<Setter Property="Background" Value="{DynamicResource CardBackgroundFillColorDefaultBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource CardStrokeColorDefaultBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="10"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Color="#000000" Opacity="0.18" BlurRadius="20" ShadowDepth="4"/>
</Setter.Value>
</Setter>
</Style>
<!-- ── Device row button — hover tint indicates intent (connect=blue, disconnect=red) -->
<Style x:Key="DeviceRow" TargetType="Button">
<Setter Property="Background" Value="{DynamicResource ControlFillColorSecondaryBrush}"/>