@* Dispatch page: reads DriverInstance.DriverType and renders the matching typed editor via . Falls back to the legacy DriverEdit for any type not yet in the map. The route collides with DriverEdit.razor's identical directive — that's intentional. Task 3.4 removes the route from DriverEdit.razor. Blazor route conflicts are runtime, not build-time, so the build succeeds now. *@ @page "/clusters/{ClusterId}/drivers/{DriverInstanceId}" @attribute [Microsoft.AspNetCore.Authorization.Authorize] @rendermode RenderMode.InteractiveServer @using Microsoft.EntityFrameworkCore @using ZB.MOM.WW.OtOpcUa.Configuration @using ZB.MOM.WW.OtOpcUa.Configuration.Entities @inject IDbContextFactory DbFactory @if (!_loaded) {

Loading…

} else if (_existing is null) {

Edit driver instance · @ClusterId

Cancel
Driver instance @DriverInstanceId was not found in cluster @ClusterId.
} else { } @code { [Parameter] public string ClusterId { get; set; } = ""; [Parameter] public string DriverInstanceId { get; set; } = ""; private DriverInstance? _existing; private bool _loaded; private static readonly IReadOnlyDictionary _componentMap = new Dictionary(StringComparer.OrdinalIgnoreCase) { // Populated by Phase 4 — until then, all driver types fall back to DriverEdit. // Keys must match DriverInstance.DriverType strings: // ModbusTcp, AbCip, AbLegacy, S7, TwinCat, Focas, OpcUaClient, Galaxy, Historian.Wonderware }; protected override async Task OnInitializedAsync() { await using var db = await DbFactory.CreateDbContextAsync(); _existing = await db.DriverInstances.AsNoTracking() .FirstOrDefaultAsync(d => d.ClusterId == ClusterId && d.DriverInstanceId == DriverInstanceId); _loaded = true; } private Type ResolveComponentType() => _componentMap.TryGetValue(_existing!.DriverType, out var t) ? t : typeof(ZB.MOM.WW.OtOpcUa.AdminUI.Components.Pages.Clusters.DriverEdit); private IDictionary BuildParameters() => new Dictionary { ["ClusterId"] = ClusterId, ["DriverInstanceId"] = DriverInstanceId, }; }