Files
HC_APTBS/Views/UserControls/DashboardConnectionView.xaml
LucianoDev 197e9d1775 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>
2026-04-19 22:25:00 +02:00

233 lines
15 KiB
XML

<UserControl x:Class="HC_APTBS.Views.UserControls.DashboardConnectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:models="clr-namespace:HC_APTBS.Models"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="72" d:DesignWidth="1100">
<!--
Connection status strip for the Dashboard — four horizontal chips + pump name badge.
DataContext is DashboardPageViewModel; reads Root.IsCanConnected, Root.IsBenchConnected,
Root.IsPumpConnected, Root.KLineState via DataTriggers.
-->
<Border Background="{DynamicResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
BorderThickness="1" CornerRadius="8"
Padding="14,10" Margin="0,0,0,8">
<DockPanel LastChildFill="False">
<!-- ── Pump name badge (right-docked) ──────────────────────────── -->
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Center" Margin="16,0,0,0">
<TextBlock Text="{DynamicResource Dashboard.Conn.Pump.Label}"
FontSize="12" Foreground="{DynamicResource TextFillColorSecondaryBrush}"
VerticalAlignment="Center" Margin="0,0,6,0"/>
<!-- Model name — shown when pump is selected -->
<TextBlock Text="{Binding Root.PumpIdentification.CurrentPump.Model}"
FontSize="13" FontWeight="SemiBold"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Root.PumpIdentification.CurrentPump}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<!-- Placeholder — shown when no pump is selected -->
<TextBlock Text="{DynamicResource Dashboard.Conn.NoPump}"
FontSize="12" FontStyle="Italic"
Foreground="{DynamicResource TextFillColorTertiaryBrush}"
VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Root.PumpIdentification.CurrentPump}" Value="{x:Null}">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
<!-- ── Connection chips ─────────────────────────────────────────── -->
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<!-- CAN bus chip -->
<Border Style="{StaticResource ConnChip}">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<ui:SymbolIcon Symbol="PlugConnected24" FontSize="15"
Foreground="{DynamicResource TextFillColorSecondaryBrush}" Margin="0,0,6,0"/>
<TextBlock Text="{DynamicResource Dashboard.Conn.Can}" FontSize="12"
Foreground="{DynamicResource TextFillColorPrimaryBrush}" VerticalAlignment="Center"
Margin="0,0,10,0"/>
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource StatusDot}">
<Style.Triggers>
<DataTrigger Binding="{Binding Root.IsCanConnected}" Value="True">
<Setter Property="Fill" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOffline}"/>
<Setter Property="Foreground" Value="{DynamicResource TextFillColorTertiaryBrush}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Root.IsCanConnected}" Value="True">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOnline}"/>
<Setter Property="Foreground" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Border>
<!-- Bench controller chip -->
<Border Style="{StaticResource ConnChip}">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<ui:SymbolIcon Symbol="DesktopPulse24" FontSize="15"
Foreground="{DynamicResource TextFillColorSecondaryBrush}" Margin="0,0,6,0"/>
<TextBlock Text="{DynamicResource Dashboard.Conn.Bench}" FontSize="12"
Foreground="{DynamicResource TextFillColorPrimaryBrush}" VerticalAlignment="Center"
Margin="0,0,10,0"/>
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource StatusDot}">
<Style.Triggers>
<DataTrigger Binding="{Binding Root.IsBenchConnected}" Value="True">
<Setter Property="Fill" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOffline}"/>
<Setter Property="Foreground" Value="{DynamicResource TextFillColorTertiaryBrush}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Root.IsBenchConnected}" Value="True">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOnline}"/>
<Setter Property="Foreground" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Border>
<!-- Pump ECU chip -->
<Border Style="{StaticResource ConnChip}">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<ui:SymbolIcon Symbol="Server24" FontSize="15"
Foreground="{DynamicResource TextFillColorSecondaryBrush}" Margin="0,0,6,0"/>
<TextBlock Text="{DynamicResource Dashboard.Conn.Pump}" FontSize="12"
Foreground="{DynamicResource TextFillColorPrimaryBrush}" VerticalAlignment="Center"
Margin="0,0,10,0"/>
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource StatusDot}">
<Style.Triggers>
<DataTrigger Binding="{Binding Root.IsPumpConnected}" Value="True">
<Setter Property="Fill" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOffline}"/>
<Setter Property="Foreground" Value="{DynamicResource TextFillColorTertiaryBrush}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Root.IsPumpConnected}" Value="True">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOnline}"/>
<Setter Property="Foreground" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Border>
<!-- K-Line session chip -->
<Border>
<Border.Style>
<Style TargetType="Border" BasedOn="{StaticResource ConnChip}">
<Style.Triggers>
<DataTrigger Binding="{Binding Root.KLineState}"
Value="{x:Static models:KLineConnectionState.Failed}">
<Setter Property="Background" Value="{DynamicResource SystemFillColorCautionBackgroundBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource SystemFillColorCautionBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<ui:SymbolIcon Symbol="UsbPlug24" FontSize="15"
Foreground="{DynamicResource TextFillColorSecondaryBrush}" Margin="0,0,6,0"/>
<TextBlock Text="{DynamicResource Dashboard.Conn.KLine}" FontSize="12"
Foreground="{DynamicResource TextFillColorPrimaryBrush}" VerticalAlignment="Center"
Margin="0,0,10,0"/>
<Ellipse>
<Ellipse.Style>
<Style TargetType="Ellipse" BasedOn="{StaticResource StatusDot}">
<Style.Triggers>
<DataTrigger Binding="{Binding Root.KLineState}"
Value="{x:Static models:KLineConnectionState.Connected}">
<Setter Property="Fill" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Root.KLineState}"
Value="{x:Static models:KLineConnectionState.Failed}">
<Setter Property="Fill" Value="{DynamicResource SystemFillColorCautionBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock FontSize="11" FontWeight="SemiBold" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateClosed}"/>
<Setter Property="Foreground" Value="{DynamicResource TextFillColorTertiaryBrush}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Root.KLineState}"
Value="{x:Static models:KLineConnectionState.Connected}">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateOpen}"/>
<Setter Property="Foreground" Value="{DynamicResource SystemFillColorSuccessBrush}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Root.KLineState}"
Value="{x:Static models:KLineConnectionState.Failed}">
<Setter Property="Text" Value="{DynamicResource Dashboard.StateFailed}"/>
<Setter Property="Foreground" Value="{DynamicResource SystemFillColorCautionBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Border>
</StackPanel>
</DockPanel>
</Border>
</UserControl>