diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Uns/EquipmentPage.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Uns/EquipmentPage.razor index 105fa06b1..e3adbff5b 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Uns/EquipmentPage.razor +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Uns/EquipmentPage.razor @@ -311,12 +311,14 @@ else - - @* One confirm for every destructive row action on this page (R04 H1) — the same RawConfirmDialog - /raw routes its deletes through. A mis-click used to delete immediately. *@ - } + + @* One confirm for every destructive row action on this page (R04 H1) — the same RawConfirmDialog + /raw routes its deletes through. A mis-click used to delete immediately. It must render OUTSIDE the + tab branches (#832): inside the Alarms branch it existed only on that tab, so the Tags tab's Remove + and the Virtual Tags tab's Delete opened a dialog that was never on the page. *@ + } diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/DeleteConfirmationWiringTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/DeleteConfirmationWiringTests.cs index 3505c267b..767554a60 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/DeleteConfirmationWiringTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Uns/DeleteConfirmationWiringTests.cs @@ -28,6 +28,31 @@ public sealed class DeleteConfirmationWiringTests Regex.Matches(src, "btn-outline-danger").Count.ShouldBe(3); } + /// + /// #832: the shared confirm used to sit INSIDE the Alarms tab branch, so it was on the page only while that + /// tab was showing — the Tags tab's Remove and the Virtual Tags tab's Delete set the dialog visible and + /// nothing appeared. Pinned by brace depth: the dialog must be at the depth of the tab @if chain, + /// not inside any branch of it. + /// + [Fact] + public void Equipment_page_confirm_renders_outside_every_tab_branch() + { + var src = AdminUiSource.Read("Components", "Pages", "Uns", "EquipmentPage.razor"); + var markup = src[..src.IndexOf("@code", StringComparison.Ordinal)]; + + int DepthAt(int index) => + markup[..index].Count(c => c == '{') - markup[..index].Count(c => c == '}'); + + var tabChain = markup.IndexOf("@if (_activeTab == \"details\")", StringComparison.Ordinal); + var dialog = markup.IndexOf("