fix(centralui): Topology inline area rename commits the typed name on Enter (Gitea #38)

The rename input bound _renameBuffer with the default onchange trigger. A
browser fires change only after the Enter keydown (or on blur, which cancels
by design), so CommitRename always saw the original name and silently
no-oped: a UI rename never persisted. Present since the page was written
(pre-dates 513fa1aa); the Playwright test masked it by dispatching a
synthetic change event before Enter. Bind on oninput instead.

Tests: bUnit InlineRename_TypeThenEnter_PersistsNewName (fails on the old
binding); the Playwright rename test now types + Enter like an operator.
Also fix the Playwright OpenStableTopologyAsync race: it counted 'Load
instances' loaders immediately after clicking Expand all, before the
circuit re-render landed, and returned an unexpanded tree; it now waits
for no collapsed branch first.
This commit is contained in:
Joseph Doherty
2026-10-22 13:45:56 -04:00
parent 52a1e1b614
commit 560adefb0c
3 changed files with 41 additions and 6 deletions
@@ -449,6 +449,33 @@ public class TopologyPageTests : BunitContext
Assert.NotNull(cut.Find("input.form-control-sm.d-inline-block"));
}
/// <summary>
/// Gitea #38: typing a new name and pressing Enter must persist the rename. The buffer
/// used to bind on <c>onchange</c>, which a browser fires only after the Enter keydown
/// (or on blur, which cancels) — so the commit always saw the original name and no-oped.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InlineRename_TypeThenEnter_PersistsNewName()
{
var area = new Area("Line-1") { Id = 10, SiteId = 1 };
var areasBySite = new Dictionary<int, IReadOnlyList<Area>> { [1] = new List<Area> { area } };
SeedRepos(sites: new[] { new Site("Plant-A", "plant-a") { Id = 1 } }, areasBySite: areasBySite);
_repo.GetAreaByIdAsync(10, Arg.Any<CancellationToken>()).Returns(area);
var cut = RenderLoadedTopology();
FindToggleForLabel(cut, "Plant-A")!.Click();
cut.FindAll("span.tv-label").First(s => s.TextContent == "Line-1").DoubleClick();
var input = cut.Find("input[aria-label='Rename Line-1']");
// Keystroke-level binding: no change event (that only arrives after Enter, or on blur).
input.Input("Line-1-renamed");
await cut.Find("input[aria-label='Rename Line-1']").KeyDownAsync(new Microsoft.AspNetCore.Components.Web.KeyboardEventArgs { Key = "Enter" });
await _repo.Received(1).UpdateAreaAsync(
Arg.Is<Area>(a => a.Id == 10 && a.Name == "Line-1-renamed"), Arg.Any<CancellationToken>());
}
/// <summary>Verifies that instance rows do not support double-click rename.</summary>
[Fact]
public void InstanceRows_DoNotHaveDoubleClickRename()