From 55e8bf70d90190d0746fc7e5fcd34a03e009246c Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 28 May 2026 09:38:35 -0400 Subject: [PATCH] feat(adminui): add DriverEditRouter dispatch page Falls back to legacy DriverEdit until Phase 4 populates the type-map. --- .../Clusters/Drivers/DriverEditRouter.razor | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/DriverEditRouter.razor diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/DriverEditRouter.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/DriverEditRouter.razor new file mode 100644 index 00000000..79dc81fa --- /dev/null +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Clusters/Drivers/DriverEditRouter.razor @@ -0,0 +1,68 @@ +@* 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, + }; +}