Files
HC_APTBS/ViewModels/Pages/BenchPageViewModel.cs
LucianoDev 0280a2fad1 feat: page-based navigation shell + Tests page wizard
Replace the monolithic MainWindow with a SelectedPage-driven shell
(Dashboard / Pump / Bench / Tests / Results / Settings). The Tests
page gets the Plan -> Preconditions -> Running -> Done wizard from
ui-structure.md \u00a74, backed by a 7-item precondition gate and
shared sub-views (PhaseCardView / TestSectionView / GraphicIndicatorView)
extracted from the now-deleted monolithic TestPanelView.

New VMs / views:
- Tests wizard: TestPreconditions, PhaseCard, GraphicIndicator,
  TestSection, TestPlan, TestRunning, TestDone
- Dashboard panels: DashboardConnection, DashboardReadings,
  DashboardAlarms, InterlockBanner, ResultHistory
- Pump / bench panels: PumpIdentificationPanel, PumpLiveData,
  UnlockPanel, BenchDriveControl, BenchReadings, RelayBank,
  TemperatureControl, DtcList, AuthGate
- Dialogs: generic ConfirmDialog, UserManageDialog, UserPromptDialog

Supporting changes:
- IsOilPumpOn exposed on MainViewModel for precondition evaluation
- RequiresAuth added to TestDefinition (XML round-trip)
- BipStatusDefinition + CompletedTestRun models
- ~35 new Test.* localization keys (en + es)
- Settings moved from modal dialog to full page
- Pause / Retry / Skip stubs in TestRunningView; full spec in
  docs/gap-test-running-controls.md for follow-up implementation
- docs/ui-structure.md captures the wizard design

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 13:11:34 +02:00

67 lines
3.0 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using HC_APTBS.Services;
namespace HC_APTBS.ViewModels.Pages
{
/// <summary>
/// ViewModel for the Bench navigation page.
///
/// <para>Groups the bench-related child ViewModels owned by
/// <see cref="MainViewModel"/> together with page-specific façades
/// (temperature control, relay bank, pressure trace, interlock banner)
/// that only the Bench page consumes.</para>
/// </summary>
public sealed class BenchPageViewModel : ObservableObject
{
/// <summary>Root ViewModel — owns services, live readings, and global commands.</summary>
public MainViewModel Root { get; }
/// <summary>Manual bench controls (direction, RPM start/stop, oil pump, counter).</summary>
public BenchControlViewModel BenchControl => Root.BenchControl;
/// <summary>Real-time flowmeter charts (Q-Delivery, Q-Over).</summary>
public FlowmeterChartViewModel FlowmeterChart => Root.FlowmeterChart;
/// <summary>Encoder angle monitoring (PSG, INJ, Manual, Lock Angle).</summary>
public AngleDisplayViewModel AngleDisplay => Root.AngleDisplay;
/// <summary>Temperature PID setpoint + heater / cooler relay toggles.</summary>
public TemperatureControlViewModel TempControl { get; }
/// <summary>Auxiliary relay toggle bank (Electronic, Flasher, Pulse4Signal).</summary>
public RelayBankViewModel RelayBank { get; }
/// <summary>Real-time pressure traces (P1, P2).</summary>
public PressureTraceChartViewModel PressureTrace { get; } = new();
/// <summary>Soft safety interlock banner state (oil pump / RPM limit).</summary>
public InterlockBannerViewModel Interlock { get; }
/// <param name="root">Root view-model providing live bench readings and child VMs.</param>
/// <param name="benchService">Bench service for setpoint and relay control.</param>
/// <param name="configService">Configuration service for safety limits and defaults.</param>
public BenchPageViewModel(
MainViewModel root,
IBenchService benchService,
IConfigurationService configService)
{
Root = root;
TempControl = new TemperatureControlViewModel(benchService, configService);
RelayBank = new RelayBankViewModel(benchService);
Interlock = new InterlockBannerViewModel(configService);
}
/// <summary>
/// Called from <see cref="MainViewModel.OnRefreshTick"/> to feed the
/// page-scoped VMs (pressure trace, interlock banner) from the latest
/// bench readings. Keeping this here avoids adding page-specific logic
/// to the root ViewModel.
/// </summary>
public void RefreshFromTick()
{
PressureTrace.AddSamples(Root.Pressure, Root.Pressure2);
Interlock.Update(Root.BenchRpm, BenchControl.IsOilPumpOn);
}
}
}