Unlock progress UI:
- UnlockProgressDialog with dark-themed progress ring, phase indicator, elapsed
time, and cancel/close buttons (non-modal, draggable borderless window)
- UnlockProgressViewModel with event-driven progress tracking via IUnlockService
- Triggers on pump selection (manual or K-Line auto-detect), not test start
UnlockService rewrite:
- Persistent CAN senders that outlive the unlock sequence (StopSenders on pump change)
- Concurrent K-Line fast unlock: awaits session Connected, sends RAM timer shortcut
({02 88 02 03 A8 01 00}), verifies via CAN TestUnlock before skipping wait
- Fix Type 1 verification (Value == 0 means unlocked, was inverted)
K-Line fast unlock support:
- IKwpService.TryFastUnlockAsync / KwpService implementation
Additional features:
- ILocalizationService with ES/EN resource dictionaries and runtime switching
- Safety dialogs: VoltageWarning, OilPumpConfirm, RpmSafetyWarning
- SettingsDialog for app configuration
- BenchService enhancements, ConfigurationService improvements, PDF report updates
- All UI strings localized via DynamicResource
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
124 lines
4.9 KiB
C#
124 lines
4.9 KiB
C#
using System.Collections.ObjectModel;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using HC_APTBS.Models;
|
|
using HC_APTBS.Services;
|
|
|
|
namespace HC_APTBS.ViewModels
|
|
{
|
|
/// <summary>
|
|
/// Represents the display state for one phase within the test list UI.
|
|
/// Binds to a single row in the test phase grid.
|
|
/// </summary>
|
|
public sealed partial class PhaseRowViewModel : ObservableObject
|
|
{
|
|
/// <summary>Display name of the phase.</summary>
|
|
[ObservableProperty] private string _name = string.Empty;
|
|
|
|
/// <summary>True while this phase is actively executing.</summary>
|
|
[ObservableProperty] private bool _isActive;
|
|
|
|
/// <summary>True when the phase has completed and passed all criteria.</summary>
|
|
[ObservableProperty] private bool _isPassed;
|
|
|
|
/// <summary>True when the phase has completed but failed one or more criteria.</summary>
|
|
[ObservableProperty] private bool _isFailed;
|
|
|
|
/// <summary>Whether this phase is enabled for the current test run.</summary>
|
|
[ObservableProperty] private bool _isEnabled = true;
|
|
|
|
/// <summary>Short result string shown in the row (e.g. "PASS", "FAIL", "…").</summary>
|
|
[ObservableProperty] private string _resultText = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// ViewModel for the TestDisplay user control.
|
|
///
|
|
/// <para>
|
|
/// Shows the current test name, the list of phases with their pass/fail status,
|
|
/// and the verbose status message from the bench service.
|
|
/// </para>
|
|
/// </summary>
|
|
public sealed partial class TestDisplayViewModel : ObservableObject
|
|
{
|
|
private readonly ILocalizationService _loc;
|
|
|
|
/// <summary>Initialises a new test display with a localization service.</summary>
|
|
public TestDisplayViewModel(ILocalizationService loc) => _loc = loc;
|
|
// ── Properties ────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Name of the test currently being executed (e.g. "F", "SVME").</summary>
|
|
[ObservableProperty] private string _testName = string.Empty;
|
|
|
|
/// <summary>Current verbose status line from the bench service.</summary>
|
|
[ObservableProperty] private string _statusText = string.Empty;
|
|
|
|
/// <summary>Estimated total remaining time (seconds) for the entire test sequence.</summary>
|
|
[ObservableProperty] private int _remainingSeconds;
|
|
|
|
/// <summary>True while a test sequence is in progress.</summary>
|
|
[ObservableProperty] private bool _isRunning;
|
|
|
|
/// <summary>Phase rows shown in the phase list.</summary>
|
|
public ObservableCollection<PhaseRowViewModel> Phases { get; } = new();
|
|
|
|
// ── Public API ────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>
|
|
/// Populates the phase list from a <see cref="TestDefinition"/>.
|
|
/// Call when the active test changes.
|
|
/// </summary>
|
|
public void LoadTest(TestDefinition test)
|
|
{
|
|
TestName = test.Name;
|
|
Phases.Clear();
|
|
foreach (var phase in test.Phases)
|
|
{
|
|
Phases.Add(new PhaseRowViewModel
|
|
{
|
|
Name = phase.Name,
|
|
IsEnabled = phase.Enabled,
|
|
ResultText = phase.Enabled ? "\u2013" : _loc.GetString("Common.Disabled")
|
|
});
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Marks a phase as active (running), clearing any previous active state.
|
|
/// </summary>
|
|
public void SetActivePhase(string phaseName)
|
|
{
|
|
StatusText = phaseName;
|
|
foreach (var row in Phases)
|
|
{
|
|
row.IsActive = row.Name == phaseName;
|
|
}
|
|
}
|
|
|
|
/// <summary>Updates a phase row with the result of a completed phase.</summary>
|
|
public void SetPhaseResult(string phaseName, bool passed)
|
|
{
|
|
foreach (var row in Phases)
|
|
{
|
|
if (row.Name != phaseName) continue;
|
|
row.IsActive = false;
|
|
row.IsPassed = passed;
|
|
row.IsFailed = !passed;
|
|
row.ResultText = passed ? _loc.GetString("Common.Pass") : _loc.GetString("Common.Fail");
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// <summary>Clears all phase result states for a fresh test run.</summary>
|
|
public void ResetResults()
|
|
{
|
|
foreach (var row in Phases)
|
|
{
|
|
row.IsActive = false;
|
|
row.IsPassed = false;
|
|
row.IsFailed = false;
|
|
row.ResultText = row.IsEnabled ? "\u2013" : _loc.GetString("Common.Disabled");
|
|
}
|
|
}
|
|
}
|
|
}
|