From a36c813b8926159171d919c6a50a44154cf05984 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 8 Sep 2026 01:09:30 -0400 Subject: [PATCH] =?UTF-8?q?feat(central-ui):=20ParameterValueForm.ValidCha?= =?UTF-8?q?nged=20=E2=80=94=20additive=20validity=20callback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29 --- .../Components/Shared/ParameterValueForm.razor | 10 ++++++++++ .../Design/ParameterValueFormTests.cs | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Shared/ParameterValueForm.razor b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Shared/ParameterValueForm.razor index 24ca8fe8..5117bc64 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Shared/ParameterValueForm.razor +++ b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Shared/ParameterValueForm.razor @@ -48,6 +48,13 @@ else [Parameter] public Dictionary Values { get; set; } = new(); [Parameter] public EventCallback> ValuesChanged { get; set; } + /// + /// Raised after every edit with true when the value tree has no parse or validation errors + /// (Flow Debugger script entry, design 2026-09-08 ยง5: the page gates Run on it). Additive; existing + /// callers ignore it. + /// + [Parameter] public EventCallback ValidChanged { get; set; } + private IReadOnlyList _shapes = Array.Empty(); private IReadOnlyList _topLevelFields = Array.Empty(); private InboundApiSchema? _rootSchema; @@ -620,8 +627,11 @@ else { Validate(); await ValuesChanged.InvokeAsync(Values); + await ValidChanged.InvokeAsync(IsValid); } + private bool IsValid => _parseErrors.Count == 0; + // Validates the whole value tree against the parsed schema and projects each // path-qualified error onto the input that owns it. Raw-text parse failures // (numeric / JSON) are added directly by the setters; schema validation adds diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Design/ParameterValueFormTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Design/ParameterValueFormTests.cs index f968b3c8..023e2f0e 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Design/ParameterValueFormTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Design/ParameterValueFormTests.cs @@ -282,4 +282,19 @@ public class ParameterValueFormTests : BunitContext Assert.Single(cut.FindAll("button.param-list-remove")); Assert.NotEmpty(cut.FindAll(".text-danger")); } + + [Fact] + public void ValidChanged_ReportsFalseOnAParseError_AndTrueOnceFixed() + { + var valid = new List(); + var cut = Render(p => p + .Add(x => x.ParameterDefinitions, """{"type":"object","properties":{"n":{"type":"integer"}}}""") + .Add(x => x.ValidChanged, v => valid.Add(v))); + + var input = cut.Find("#param-n"); + input.Input("abc"); + Assert.False(valid.Last()); + input.Input("5"); + Assert.True(valid.Last()); + } }