fix(client-ui): resolve Low code-review findings (Client.UI-003,004,006,009,010,011)

- Client.UI-003: wire Serilog properly per CLAUDE.md — console sink +
  rolling daily file sink in Program.Main, Log.CloseAndFlush in finally,
  per-VM Log.ForContext<> loggers.
- Client.UI-004: migrate the cert-store folder picker from the obsolete
  OpenFolderDialog to StorageProvider.OpenFolderPickerAsync (with
  TryGetFolderFromPathAsync seed + TryGetLocalPath extraction).
- Client.UI-006: surface formerly silent catch blocks via an observable
  StatusMessage on the Subscriptions / Alarms VMs that bubbles up into
  the shell's status bar; soft fallbacks log at Information level so
  hard failures stay distinguishable.
- Client.UI-009: docs/Client.UI.md now lists Standard Deviation in the
  Aggregate row of the Query Options table.
- Client.UI-010: removed the unused MinDateTimeProperty /
  MaxDateTimeProperty styled properties from DateTimeRangePicker.
- Client.UI-011: updated the cert-store TextBox watermark from the
  legacy AppData/LmxOpcUaClient/pki to the canonical
  AppData/OtOpcUaClient/pki.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-23 11:25:20 -04:00
parent 59ecd18169
commit 1b10194634
14 changed files with 246 additions and 64 deletions

View File

@@ -175,12 +175,23 @@ public sealed class FakeOpcUaClientService : IOpcUaClientService
return Task.FromResult(BrowseResults);
}
/// <summary>
/// Gets or sets the exception thrown to simulate subscribe failures in the UI.
/// </summary>
public Exception? SubscribeException { get; set; }
/// <summary>
/// Gets or sets the exception thrown to simulate alarm-subscribe failures in the UI.
/// </summary>
public Exception? SubscribeAlarmsException { get; set; }
/// <inheritdoc />
public Task SubscribeAsync(NodeId nodeId, int intervalMs = 1000, CancellationToken ct = default)
{
SubscribeCallCount++;
LastSubscribeNodeId = nodeId;
LastSubscribeIntervalMs = intervalMs;
if (SubscribeException != null) throw SubscribeException;
return Task.CompletedTask;
}
@@ -196,6 +207,7 @@ public sealed class FakeOpcUaClientService : IOpcUaClientService
public Task SubscribeAlarmsAsync(NodeId? sourceNodeId = null, int intervalMs = 1000, CancellationToken ct = default)
{
SubscribeAlarmsCallCount++;
if (SubscribeAlarmsException != null) throw SubscribeAlarmsException;
return Task.CompletedTask;
}