refactor(adminui): B2-WP8 DriverTypeNames rewire + retire routed driver-authoring flow

Part 1 — rewire the three DriverType dispatch maps from hand-authored string
literals to the canonical DriverTypeNames constants (single source of truth):
- TagConfigEditorMap, TagConfigValidator (AdminUI)
- EquipmentTagConfigInspector (ControlPlane)
This FIXES the live drift ("TwinCat"->TwinCAT, "Focas"->FOCAS). The maps are
OrdinalIgnoreCase so behavior is identical; the value is no future drift.
Calculation is not added to the inspector (no CalculationTagDefinitionFactory.Inspect).
Added TagConfigDriverTypeNameGuardTests pinning the maps to the constants.

Part 2 — retire the routed /clusters/{id}/drivers driver-authoring flow (/raw
Waves A-C now cover driver/device/tag authoring end-to-end):
- Deleted DriverTypePicker, DriverEditRouter, the 8 *DriverPage shells, and the
  ClusterDrivers list page.
- Removed the "Drivers" tab from ClusterNav. Routes /clusters/{id}/drivers* now
  simply do not exist -> clean 404.
- The Forms/DeviceForms bodies, shared driver sections, and address pickers used
  by the /raw modals are untouched.

Part 3 — updated PageAuthorizationGuardTests census: removed the 10 deleted
ConfigEditor pages + ClusterDrivers, updated group-count comments (ConfigEditor
21->11, AuthenticatedRead 17->16). Removed the now-dead Clusters.Drivers usings
from the 4 *DriverPageFormSerializationTests + the guard test.

Claude-Session: https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox
This commit is contained in:
Joseph Doherty
2026-07-16 04:39:22 -04:00
parent dc80a3b4f6
commit 96471d2345
21 changed files with 103 additions and 1927 deletions
@@ -1,23 +1,26 @@
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
/// <summary>
/// Maps a driver's <c>DriverType</c> string to its typed tag-config editor component (mirrors
/// <c>DriverEditRouter._componentMap</c>). Drivers absent from the map fall back to the generic
/// raw-JSON textarea in the TagModal.
/// Maps a driver's <c>DriverType</c> string to its typed tag-config editor component. Drivers absent
/// from the map fall back to the generic raw-JSON textarea in the TagModal. Keys are the canonical
/// <see cref="DriverTypeNames"/> constants
/// (case-insensitive) so this map can never drift from the authoritative factory names.
/// </summary>
public static class TagConfigEditorMap
{
private static readonly IReadOnlyDictionary<string, Type> Map =
new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
{
["Modbus"] = typeof(Components.Shared.Uns.TagEditors.ModbusTagConfigEditor),
["S7"] = typeof(Components.Shared.Uns.TagEditors.S7TagConfigEditor),
["AbCip"] = typeof(Components.Shared.Uns.TagEditors.AbCipTagConfigEditor),
["AbLegacy"] = typeof(Components.Shared.Uns.TagEditors.AbLegacyTagConfigEditor),
["TwinCat"] = typeof(Components.Shared.Uns.TagEditors.TwinCATTagConfigEditor),
["Focas"] = typeof(Components.Shared.Uns.TagEditors.FocasTagConfigEditor),
["OpcUaClient"] = typeof(Components.Shared.Uns.TagEditors.OpcUaClientTagConfigEditor),
["Calculation"] = typeof(Components.Shared.Uns.TagEditors.CalculationTagConfigEditor),
[DriverTypeNames.Modbus] = typeof(Components.Shared.Uns.TagEditors.ModbusTagConfigEditor),
[DriverTypeNames.S7] = typeof(Components.Shared.Uns.TagEditors.S7TagConfigEditor),
[DriverTypeNames.AbCip] = typeof(Components.Shared.Uns.TagEditors.AbCipTagConfigEditor),
[DriverTypeNames.AbLegacy] = typeof(Components.Shared.Uns.TagEditors.AbLegacyTagConfigEditor),
[DriverTypeNames.TwinCAT] = typeof(Components.Shared.Uns.TagEditors.TwinCATTagConfigEditor),
[DriverTypeNames.FOCAS] = typeof(Components.Shared.Uns.TagEditors.FocasTagConfigEditor),
[DriverTypeNames.OpcUaClient] = typeof(Components.Shared.Uns.TagEditors.OpcUaClientTagConfigEditor),
[DriverTypeNames.Calculation] = typeof(Components.Shared.Uns.TagEditors.CalculationTagConfigEditor),
};
/// <summary>Returns the editor component type for a driver type, or null if none is registered.</summary>
@@ -1,3 +1,5 @@
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
/// <summary>
@@ -5,21 +7,22 @@ namespace ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
/// <see cref="TagConfigEditorMap"/>). Each entry parses the tag's config JSON into the driver's typed
/// model and runs its <c>Validate()</c>. Returns an error string to block the TagModal save, or null
/// when the config is valid — or when no typed validator is registered (unmapped drivers use the raw
/// textarea and are validated server-side at deploy).
/// textarea and are validated server-side at deploy). Keys are the canonical
/// <see cref="DriverTypeNames"/> constants (case-insensitive) so this map can never drift.
/// </summary>
public static class TagConfigValidator
{
private static readonly IReadOnlyDictionary<string, Func<string?, string?>> Validators =
new Dictionary<string, Func<string?, string?>>(StringComparer.OrdinalIgnoreCase)
{
["Modbus"] = j => ModbusTagConfigModel.FromJson(j).Validate(),
["S7"] = j => S7TagConfigModel.FromJson(j).Validate(),
["AbCip"] = j => AbCipTagConfigModel.FromJson(j).Validate(),
["AbLegacy"] = j => AbLegacyTagConfigModel.FromJson(j).Validate(),
["TwinCat"] = j => TwinCATTagConfigModel.FromJson(j).Validate(),
["Focas"] = j => FocasTagConfigModel.FromJson(j).Validate(),
["OpcUaClient"] = j => OpcUaClientTagConfigModel.FromJson(j).Validate(),
["Calculation"] = j => CalculationTagConfigModel.FromJson(j).Validate(),
[DriverTypeNames.Modbus] = j => ModbusTagConfigModel.FromJson(j).Validate(),
[DriverTypeNames.S7] = j => S7TagConfigModel.FromJson(j).Validate(),
[DriverTypeNames.AbCip] = j => AbCipTagConfigModel.FromJson(j).Validate(),
[DriverTypeNames.AbLegacy] = j => AbLegacyTagConfigModel.FromJson(j).Validate(),
[DriverTypeNames.TwinCAT] = j => TwinCATTagConfigModel.FromJson(j).Validate(),
[DriverTypeNames.FOCAS] = j => FocasTagConfigModel.FromJson(j).Validate(),
[DriverTypeNames.OpcUaClient] = j => OpcUaClientTagConfigModel.FromJson(j).Validate(),
[DriverTypeNames.Calculation] = j => CalculationTagConfigModel.FromJson(j).Validate(),
};
/// <summary>