using System; using CommunityToolkit.Mvvm.ComponentModel; using Junction.Domain.Models; namespace Junction.App.ViewModels { /// /// One dashboard row = one configured machine + its latest snapshot projection. /// Mutated only on the UI thread (see marshalling). /// public sealed partial class MachineRowViewModel : ViewModelBase { public Guid MachineId { get; } [ObservableProperty] private string _name; [ObservableProperty] private string _protocolId; [ObservableProperty] private ConnectionState _connectionState; [ObservableProperty] private string _lastDatum; [ObservableProperty] private string _lastUpdated; public MachineRowViewModel(Machine machine) { MachineId = machine.Id; _name = machine.Name; _protocolId = machine.ProtocolId; _connectionState = ConnectionState.Unknown; _lastDatum = "—"; _lastUpdated = "—"; } /// Projects a snapshot onto this row. Call on the UI thread. public void Apply(MachineSnapshot snapshot) { if (snapshot == null) { return; } ConnectionState = snapshot.ConnectionState; LastUpdated = snapshot.CapturedAt.LocalDateTime.ToString("HH:mm:ss"); LastDatum = Representative(snapshot); } /// /// Picks a human-meaningful datum to show: prefer an availability/execution item, /// else the first item's value, else an em-dash placeholder. /// private static string Representative(MachineSnapshot snapshot) { if (snapshot.Items.Count == 0) { return "—"; } DataItem? preferred = null; for (int i = 0; i < snapshot.Items.Count; i++) { var item = snapshot.Items[i]; if (Matches(item.Id) || Matches(item.Name)) { preferred = item; break; } } var chosen = preferred ?? snapshot.Items[0]; var value = string.IsNullOrWhiteSpace(chosen.Value) ? "—" : chosen.Value; var label = string.IsNullOrWhiteSpace(chosen.Name) ? chosen.Id : chosen.Name; return string.IsNullOrWhiteSpace(label) ? value : label + " = " + value; } private static bool Matches(string s) { if (string.IsNullOrEmpty(s)) { return false; } return s.IndexOf("avail", StringComparison.OrdinalIgnoreCase) >= 0 || s.IndexOf("execution", StringComparison.OrdinalIgnoreCase) >= 0; } } }