refactor(ui/design): replace JSON inputs with structured editors

Two new shared components in Components/Shared:
  - ParameterListEditor: table of rows (name + type + item type + required + remove)
  - ReturnTypeEditor: single type (+ item type when List)

Both round-trip the same JSON shape already stored on the entity:
  parameters: [{"name":"x","type":"String","required":true},...]
  return:     {"type":"List","itemType":"Integer"} | null

Type set follows the Inbound API validator (Boolean, Integer, Float,
String, Object, List). Legacy values normalize on read — Int32 / int64
/ Double / Decimal / lowercase string / etc all coalesce to the new
set so existing rows render correctly. Re-saving persists the
normalized form.

Applied to:
  - SharedScriptForm
  - TemplateEdit Add Script form (also surfaces ParameterDefinitions
    + ReturnDefinition which the entity supported but the form was
    never wiring through)
  - ApiMethodForm

Graceful degradation: invalid JSON is shown with a "Start fresh"
escape hatch instead of crashing the form.
This commit is contained in:
Joseph Doherty
2026-05-12 04:22:58 -04:00
parent eb1d6872ef
commit 1b98d37919
5 changed files with 343 additions and 25 deletions

View File

@@ -85,6 +85,8 @@
private string _scriptCode = string.Empty;
private string? _scriptTriggerType;
private string? _scriptTriggerConfig;
private string? _scriptParameters;
private string? _scriptReturn;
private bool _scriptIsLocked;
private string? _scriptFormError;
@@ -615,7 +617,7 @@
{
<div class="d-flex justify-content-between align-items-center mb-2">
<h5 class="mb-0">Scripts</h5>
<button class="btn btn-primary btn-sm" @onclick="() => { _showScriptForm = true; _scriptFormError = null; _scriptName = string.Empty; _scriptCode = string.Empty; _scriptTriggerType = null; _scriptTriggerConfig = null; _scriptIsLocked = false; }">Add Script</button>
<button class="btn btn-primary btn-sm" @onclick="() => { _showScriptForm = true; _scriptFormError = null; _scriptName = string.Empty; _scriptCode = string.Empty; _scriptTriggerType = null; _scriptTriggerConfig = null; _scriptParameters = null; _scriptReturn = null; _scriptIsLocked = false; }">Add Script</button>
</div>
@if (_showScriptForm)
@@ -636,6 +638,14 @@
<label class="form-label">Trigger Config (JSON)</label>
<input type="text" class="form-control" @bind="_scriptTriggerConfig" />
</div>
<div class="col-12">
<label class="form-label">Parameters</label>
<ParameterListEditor Json="@_scriptParameters" JsonChanged="@(v => _scriptParameters = v)" />
</div>
<div class="col-12">
<label class="form-label">Return value</label>
<ReturnTypeEditor Json="@_scriptReturn" JsonChanged="@(v => _scriptReturn = v)" />
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" @bind="_scriptIsLocked" id="scriptLocked" />
@@ -884,6 +894,8 @@
{
TriggerType = _scriptTriggerType?.Trim(),
TriggerConfiguration = _scriptTriggerConfig?.Trim(),
ParameterDefinitions = _scriptParameters,
ReturnDefinition = _scriptReturn,
IsLocked = _scriptIsLocked
};