feat(dcl+ui): rename BrowseOpcUaNode -> ConnectionName-keyed; implement site handler + dialog failure mapping
- BrowseOpcUaNodeCommand: int DataConnectionId -> string ConnectionName (site DataConnectionManagerActor indexes children by name; CentralUI already has the connection name in scope via the dropdown — no extra plumbing across the trust boundary). - IOpcUaBrowseService / OpcUaBrowseService: parameter renamed accordingly. - OpcUaBrowserDialog: collapse the duplicate ConnectionName parameters (display label and routing key are the same string). - Task 10: DataConnectionManagerActor forwards BrowseOpcUaNodeCommand to its child by name (owns ConnectionNotFound); DataConnectionActor adds the receive across all three lifecycle states (Connecting / Connected / Reconnecting) and maps adapter outcomes to BrowseFailureKind (NotBrowsable / ConnectionNotConnected / Timeout / ServerError). - Task 17: SetFailure in OpcUaBrowserDialog implements the full BrowseFailureKind switch with friendly UI messages. - Tests: DataConnectionManagerBrowseHandlerTests covers ConnectionNotFound, NotBrowsable, success, and ConnectionNotConnectedException paths.
This commit is contained in:
@@ -57,7 +57,12 @@
|
||||
|
||||
@code {
|
||||
[Parameter] public string SiteId { get; set; } = "";
|
||||
[Parameter] public int DataConnectionId { get; set; }
|
||||
/// <summary>
|
||||
/// Name of the site-local data connection. Serves both as the modal-header
|
||||
/// display label AND as the routing key for the browse round-trip — the
|
||||
/// site's <c>DataConnectionManagerActor</c> indexes its children by
|
||||
/// connection name (no id-keyed lookup at the site).
|
||||
/// </summary>
|
||||
[Parameter] public string ConnectionName { get; set; } = "";
|
||||
[Parameter] public string? InitialNodeId { get; set; }
|
||||
[Parameter] public EventCallback<string> OnSelected { get; set; }
|
||||
@@ -105,7 +110,7 @@
|
||||
_rootNodes = new();
|
||||
StateHasChanged();
|
||||
|
||||
var result = await BrowseService.BrowseChildrenAsync(SiteId, DataConnectionId, parentNodeId: null);
|
||||
var result = await BrowseService.BrowseChildrenAsync(SiteId, ConnectionName, parentNodeId: null);
|
||||
if (result.Failure is not null)
|
||||
{
|
||||
SetFailure(result.Failure);
|
||||
@@ -130,7 +135,7 @@
|
||||
{
|
||||
node.Loading = true;
|
||||
StateHasChanged();
|
||||
var result = await BrowseService.BrowseChildrenAsync(SiteId, DataConnectionId, node.NodeId);
|
||||
var result = await BrowseService.BrowseChildrenAsync(SiteId, ConnectionName, node.NodeId);
|
||||
node.Loading = false;
|
||||
|
||||
if (result.Failure is not null)
|
||||
@@ -155,12 +160,23 @@
|
||||
_manualNodeId = node.NodeId;
|
||||
}
|
||||
|
||||
// NOTE: Task 17 will replace this body with the full BrowseFailureKind switch
|
||||
// that maps each failure kind to a friendly UI message.
|
||||
// Task 17: map each BrowseFailureKind to a friendly UI message. The raw
|
||||
// failure.Message is surfaced verbatim only for ServerError (which carries
|
||||
// the OPC UA SDK's own Bad_* text) and as the default fallback for any
|
||||
// future failure kind added without a UI mapping.
|
||||
private void SetFailure(BrowseFailure failure)
|
||||
{
|
||||
_failure = failure;
|
||||
_failureMessage = failure.Message;
|
||||
_failureMessage = failure.Kind switch
|
||||
{
|
||||
BrowseFailureKind.ConnectionNotFound => "Connection no longer exists at the site.",
|
||||
BrowseFailureKind.ConnectionNotConnected => "OPC UA session not connected — retry shortly or use manual entry.",
|
||||
BrowseFailureKind.NotBrowsable => "This connection does not support browsing.",
|
||||
BrowseFailureKind.Timeout => "Browse timed out — the server may be slow. Try again or enter the node id manually.",
|
||||
BrowseFailureKind.ServerError => $"OPC UA server error: {failure.Message}",
|
||||
_ => failure.Message
|
||||
};
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private Task RetryRootLoad() => LoadRootAsync();
|
||||
|
||||
@@ -21,17 +21,17 @@ public interface IOpcUaBrowseService
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumerates the immediate children of an OPC UA node on the live server
|
||||
/// backing <paramref name="dataConnectionId"/> at <paramref name="siteId"/>.
|
||||
/// backing <paramref name="connectionName"/> at <paramref name="siteId"/>.
|
||||
/// Pass <c>null</c> for <paramref name="parentNodeId"/> to browse from the
|
||||
/// server root (ObjectsFolder).
|
||||
/// </summary>
|
||||
/// <param name="siteId">The target site identifier.</param>
|
||||
/// <param name="dataConnectionId">Id of the site-local data connection to browse against.</param>
|
||||
/// <param name="connectionName">Name of the site-local data connection to browse against — the site's <c>DataConnectionManagerActor</c> indexes its children by name.</param>
|
||||
/// <param name="parentNodeId">Node to browse, or <c>null</c> to browse from the server root.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
Task<BrowseOpcUaNodeResult> BrowseChildrenAsync(
|
||||
string siteId,
|
||||
int dataConnectionId,
|
||||
string connectionName,
|
||||
string? parentNodeId,
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public sealed class OpcUaBrowseService : IOpcUaBrowseService
|
||||
/// <inheritdoc/>
|
||||
public async Task<BrowseOpcUaNodeResult> BrowseChildrenAsync(
|
||||
string siteId,
|
||||
int dataConnectionId,
|
||||
string connectionName,
|
||||
string? parentNodeId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -56,7 +56,7 @@ public sealed class OpcUaBrowseService : IOpcUaBrowseService
|
||||
{
|
||||
return await _communication.BrowseOpcUaNodeAsync(
|
||||
siteId,
|
||||
new BrowseOpcUaNodeCommand(dataConnectionId, parentNodeId),
|
||||
new BrowseOpcUaNodeCommand(connectionName, parentNodeId),
|
||||
cancellationToken);
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
|
||||
Reference in New Issue
Block a user