From f1c4392b0d0ab22f00743022b28af491d4b22ec9 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 11 Jun 2026 15:11:28 -0400 Subject: [PATCH] refactor(uns): drop dead LoadEquipmentChildrenAsync + LinesForCluster; fix stale comment --- .../Components/Pages/Uns/GlobalUns.razor | 16 +--- .../Uns/IUnsTreeService.cs | 14 +--- .../Uns/UnsTreeService.cs | 45 ---------- .../Uns/UnsTreeServiceLazyTests.cs | 82 ------------------- 4 files changed, 4 insertions(+), 153 deletions(-) delete mode 100644 tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceLazyTests.cs diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Uns/GlobalUns.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Uns/GlobalUns.razor index a026185a..d5c23d24 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Uns/GlobalUns.razor +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Uns/GlobalUns.razor @@ -151,18 +151,6 @@ .Select(a => (a.EntityId!, a.DisplayName)) .ToList(); - /// Returns the (Id, Display) line options inside a single cluster, for the equipment picker. - private IReadOnlyList<(string Id, string Display)> LinesForCluster(string? clusterId) => - _roots - .SelectMany(ent => ent.Children) - .Where(c => c.Kind == UnsNodeKind.Cluster && c.ClusterId == clusterId) - .SelectMany(c => c.Children) - .Where(a => a.Kind == UnsNodeKind.Area) - .SelectMany(a => a.Children) - .Where(l => l.Kind == UnsNodeKind.Line && l.EntityId is not null) - .Select(l => (l.EntityId!, l.DisplayName)) - .ToList(); - /// /// Toggles a structural node's expansion. Equipment nodes are leaves (no expander), /// so this path only ever fires for Enterprise/Cluster/Area/Line. @@ -370,8 +358,8 @@ } /// - /// Expands every structural node (Enterprise/Cluster/Area/Line). Equipment nodes - /// are intentionally left collapsed because expanding them would trigger lazy loads. + /// Expands every structural container node (Enterprise/Cluster/Area/Line) in the tree. + /// Equipment is a leaf node and has no expansion; skips it. /// private void ExpandAll() { diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/IUnsTreeService.cs b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/IUnsTreeService.cs index 9a3617c2..4f12c413 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/IUnsTreeService.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/IUnsTreeService.cs @@ -103,8 +103,8 @@ public sealed record EquipmentImportResult(int Inserted, int Skipped, IReadOnlyL /// /// Loads the structural portion of the unified-namespace (UNS) browse tree — /// Enterprise → Cluster → Area → Line → Equipment — from the config database. -/// Equipment children (tags/virtual tags) are summarised by count only and loaded -/// lazily by the renderer via . +/// Equipment is a leaf in the tree; its tags and virtual tags are accessed via the +/// equipment detail page, not via lazy tree expansion. /// public interface IUnsTreeService { @@ -117,16 +117,6 @@ public interface IUnsTreeService /// The enterprise root nodes, each populated down to equipment. Task> LoadStructureAsync(CancellationToken ct = default); - /// - /// Lazily loads the Tag and VirtualTag leaf nodes for a single equipment node. - /// Tags are returned first (ordered by Name), followed by VirtualTags (ordered by Name). - /// Leaf nodes carry ChildCount = 0 and HasLazyChildren = false. - /// - /// The equipment whose children to load. - /// A token to cancel the load. - /// Tag nodes followed by VirtualTag nodes; empty if the equipment has none. - Task> LoadEquipmentChildrenAsync(string equipmentId, CancellationToken ct = default); - /// /// Loads the driver tags bound to a single equipment as flat row projections for the equipment /// page's Tags tab table, ordered by Name. Each row carries the display columns plus the diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/UnsTreeService.cs b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/UnsTreeService.cs index e8094890..e0c0e656 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/UnsTreeService.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/UnsTreeService.cs @@ -82,51 +82,6 @@ public sealed class UnsTreeService(IDbContextFactory dbF return UnsTreeAssembly.Build(clusters, areas, lines, equipment); } - /// - public async Task> LoadEquipmentChildrenAsync( - string equipmentId, - CancellationToken ct = default) - { - await using var db = await dbFactory.CreateDbContextAsync(ct); - - var tagNodes = await db.Tags - .AsNoTracking() - .Where(t => t.EquipmentId == equipmentId) - .OrderBy(t => t.Name) - .Select(t => new UnsNode - { - Kind = UnsNodeKind.Tag, - Key = $"tag:{t.TagId}", - DisplayName = $"{t.Name} ({t.DataType})", - EntityId = t.TagId, - ClusterId = null, - ChildCount = 0, - HasLazyChildren = false, - }) - .ToListAsync(ct); - - var vtagNodes = await db.VirtualTags - .AsNoTracking() - .Where(v => v.EquipmentId == equipmentId) - .OrderBy(v => v.Name) - .Select(v => new UnsNode - { - Kind = UnsNodeKind.VirtualTag, - Key = $"vtag:{v.VirtualTagId}", - DisplayName = $"{v.Name} (VirtualTag)", - EntityId = v.VirtualTagId, - ClusterId = null, - ChildCount = 0, - HasLazyChildren = false, - }) - .ToListAsync(ct); - - var result = new List(tagNodes.Count + vtagNodes.Count); - result.AddRange(tagNodes); - result.AddRange(vtagNodes); - return result; - } - /// public async Task> LoadTagsForEquipmentAsync(string equipmentId, CancellationToken ct = default) { diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceLazyTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceLazyTests.cs deleted file mode 100644 index f6403580..00000000 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/UnsTreeServiceLazyTests.cs +++ /dev/null @@ -1,82 +0,0 @@ -using Shouldly; -using Xunit; -using ZB.MOM.WW.OtOpcUa.AdminUI.Uns; - -namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns; - -/// -/// Verifies returns Tag leaf nodes -/// followed by VirtualTag leaf nodes, in Name order, with the correct keys and display names. -/// -[Trait("Category", "Unit")] -public sealed class UnsTreeServiceLazyTests -{ - private static UnsTreeService SeededService() - { - var dbName = $"uns-lazy-{Guid.NewGuid():N}"; - UnsTreeTestDb.SeedNamed(dbName); - return new UnsTreeService(UnsTreeTestDb.Factory(dbName)); - } - - /// - /// Tags come first, ordered by Name, then VirtualTags; keys follow the tag:/vtag: scheme - /// and the Tag display name embeds the DataType. - /// - [Fact] - public async Task LoadEquipmentChildren_returns_tags_then_vtags() - { - var service = SeededService(); - - var children = await service.LoadEquipmentChildrenAsync(UnsTreeTestDb.SeededEquipmentId); - - // Seed has 2 tags (speed=Float, running=Boolean) + 1 vtag (computed). - // Tags are ordered by Name: "running" < "speed". - children.Count.ShouldBe(3); - - var running = children[0]; - running.Kind.ShouldBe(UnsNodeKind.Tag); - running.Key.ShouldBe("tag:TAG-2"); - running.EntityId.ShouldBe("TAG-2"); - running.ClusterId.ShouldBeNull(); - running.DisplayName.ShouldContain("running"); - running.DisplayName.ShouldContain("Boolean"); - running.ChildCount.ShouldBe(0); - running.HasLazyChildren.ShouldBeFalse(); - running.Children.ShouldBeEmpty(); - - var speed = children[1]; - speed.Kind.ShouldBe(UnsNodeKind.Tag); - speed.Key.ShouldBe("tag:TAG-1"); - speed.EntityId.ShouldBe("TAG-1"); - speed.DisplayName.ShouldContain("speed"); - speed.DisplayName.ShouldContain("Float"); - - var vtag = children[2]; - vtag.Kind.ShouldBe(UnsNodeKind.VirtualTag); - vtag.Key.ShouldBe("vtag:VTAG-1"); - vtag.EntityId.ShouldBe("VTAG-1"); - vtag.ClusterId.ShouldBeNull(); - vtag.DisplayName.ShouldContain("computed"); - vtag.DisplayName.ShouldContain("VirtualTag"); - vtag.ChildCount.ShouldBe(0); - vtag.HasLazyChildren.ShouldBeFalse(); - vtag.Children.ShouldBeEmpty(); - } - - /// An equipment with no tags or virtual tags returns an empty list. - [Fact] - public async Task LoadEquipmentChildren_empty_for_equipment_with_none() - { - // Use a fresh named store and add an equipment with no tags/vtags. - var dbName = $"uns-lazy-empty-{Guid.NewGuid():N}"; - UnsTreeTestDb.SeedNamed(dbName); - - // The orphan equipment id is not in the seeded fixture, so just use a novel id. - const string emptyEquipmentId = "EQ-NO-TAGS"; - var service = new UnsTreeService(UnsTreeTestDb.Factory(dbName)); - - var children = await service.LoadEquipmentChildrenAsync(emptyEquipmentId); - - children.ShouldBeEmpty(); - } -}