feat(central-ui): ParameterValueForm.ValidChanged — additive validity callback
Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
@@ -48,6 +48,13 @@ else
|
|||||||
[Parameter] public Dictionary<string, object?> Values { get; set; } = new();
|
[Parameter] public Dictionary<string, object?> Values { get; set; } = new();
|
||||||
[Parameter] public EventCallback<Dictionary<string, object?>> ValuesChanged { get; set; }
|
[Parameter] public EventCallback<Dictionary<string, object?>> ValuesChanged { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised after every edit with <c>true</c> 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.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter] public EventCallback<bool> ValidChanged { get; set; }
|
||||||
|
|
||||||
private IReadOnlyList<ParameterShape> _shapes = Array.Empty<ParameterShape>();
|
private IReadOnlyList<ParameterShape> _shapes = Array.Empty<ParameterShape>();
|
||||||
private IReadOnlyList<InboundApiSchemaField> _topLevelFields = Array.Empty<InboundApiSchemaField>();
|
private IReadOnlyList<InboundApiSchemaField> _topLevelFields = Array.Empty<InboundApiSchemaField>();
|
||||||
private InboundApiSchema? _rootSchema;
|
private InboundApiSchema? _rootSchema;
|
||||||
@@ -620,8 +627,11 @@ else
|
|||||||
{
|
{
|
||||||
Validate();
|
Validate();
|
||||||
await ValuesChanged.InvokeAsync(Values);
|
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
|
// 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
|
// path-qualified error onto the input that owns it. Raw-text parse failures
|
||||||
// (numeric / JSON) are added directly by the setters; schema validation adds
|
// (numeric / JSON) are added directly by the setters; schema validation adds
|
||||||
|
|||||||
@@ -282,4 +282,19 @@ public class ParameterValueFormTests : BunitContext
|
|||||||
Assert.Single(cut.FindAll("button.param-list-remove"));
|
Assert.Single(cut.FindAll("button.param-list-remove"));
|
||||||
Assert.NotEmpty(cut.FindAll(".text-danger"));
|
Assert.NotEmpty(cut.FindAll(".text-danger"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ValidChanged_ReportsFalseOnAParseError_AndTrueOnceFixed()
|
||||||
|
{
|
||||||
|
var valid = new List<bool>();
|
||||||
|
var cut = Render<ParameterValueForm>(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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user