@using ScadaLink.CentralUI.ScriptAnalysis @using System.Text.Json @* Renders an input row per declared parameter so the user can supply values for a script test run. Primitive types get typed inputs (text / number / checkbox); Object and List fall back to a JSON textarea with inline parse errors. The companion SchemaBuilder edits the schema; this edits values. *@ @if (Shapes.Count == 0) {
No parameters declared.
} else {
@foreach (var shape in Shapes) {
@RenderInput(shape) @if (_parseErrors.TryGetValue(shape.Name, out var err)) {
@err
}
}
} @code { [Parameter] public string? ParameterDefinitions { get; set; } [Parameter] public Dictionary Values { get; set; } = new(); [Parameter] public EventCallback> ValuesChanged { get; set; } private IReadOnlyList Shapes => ScriptParameterNames.ParseShapes(ParameterDefinitions); private readonly Dictionary _rawText = new(); private readonly Dictionary _parseErrors = new(); private static string FieldId(ParameterShape shape) => $"param-{shape.Name}"; private RenderFragment RenderInput(ParameterShape shape) => __builder => { switch (shape.Type) { case "Boolean":
break; case "Integer": break; case "Float": break; case "String": break; default: // Object, List, List<...>, unknown break; } }; private string AsRaw(string name) => _rawText.TryGetValue(name, out var raw) ? raw : ""; private bool AsBool(string name) => Values.TryGetValue(name, out var v) && v is bool b && b; private async Task SetString(string name, string? raw) { _rawText[name] = raw ?? ""; _parseErrors.Remove(name); Values[name] = raw ?? ""; await ValuesChanged.InvokeAsync(Values); } private async Task SetBool(string name, bool value) { _parseErrors.Remove(name); Values[name] = value; await ValuesChanged.InvokeAsync(Values); } private async Task SetNumeric(string name, string? raw, bool integerOnly) { _rawText[name] = raw ?? ""; if (string.IsNullOrWhiteSpace(raw)) { _parseErrors.Remove(name); Values.Remove(name); await ValuesChanged.InvokeAsync(Values); return; } if (integerOnly && long.TryParse(raw, out var i)) { _parseErrors.Remove(name); Values[name] = i; } else if (!integerOnly && double.TryParse(raw, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out var d)) { _parseErrors.Remove(name); Values[name] = d; } else { _parseErrors[name] = integerOnly ? "Not a valid integer." : "Not a valid number."; Values.Remove(name); } await ValuesChanged.InvokeAsync(Values); } private async Task SetJson(string name, string? raw) { _rawText[name] = raw ?? ""; if (string.IsNullOrWhiteSpace(raw)) { _parseErrors.Remove(name); Values.Remove(name); await ValuesChanged.InvokeAsync(Values); return; } try { using var doc = JsonDocument.Parse(raw); Values[name] = JsonElementToObject(doc.RootElement.Clone()); _parseErrors.Remove(name); } catch (JsonException ex) { _parseErrors[name] = $"JSON parse error: {ex.Message}"; Values.Remove(name); } await ValuesChanged.InvokeAsync(Values); } private static object? JsonElementToObject(JsonElement element) { return element.ValueKind switch { JsonValueKind.String => element.GetString(), JsonValueKind.Number => element.TryGetInt64(out var i) ? (object)i : element.GetDouble(), JsonValueKind.True => true, JsonValueKind.False => false, JsonValueKind.Null => null, JsonValueKind.Array => element.EnumerateArray().Select(JsonElementToObject).ToList(), JsonValueKind.Object => element.EnumerateObject() .ToDictionary(p => p.Name, p => JsonElementToObject(p.Value)), _ => null }; } }