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:
@@ -29,14 +29,12 @@
|
||||
<input type="number" class="form-control" @bind="_timeoutSeconds" min="1" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Params (JSON)</label>
|
||||
<input type="text" class="form-control" @bind="_params"
|
||||
placeholder='[{"name":"id","type":"Int32"}]' />
|
||||
<label class="form-label">Parameters</label>
|
||||
<ParameterListEditor Json="@_params" JsonChanged="@(v => _params = v)" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Returns (JSON)</label>
|
||||
<input type="text" class="form-control" @bind="_returns"
|
||||
placeholder='{"type":"Boolean"}' />
|
||||
<label class="form-label">Return value</label>
|
||||
<ReturnTypeEditor Json="@_returns" JsonChanged="@(v => _returns = v)" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Script</label>
|
||||
|
||||
@@ -29,25 +29,13 @@
|
||||
<input type="text" class="form-control form-control-sm" @bind="_formName"
|
||||
disabled="@(Id.HasValue)" />
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label small">
|
||||
Parameters (JSON)
|
||||
<span class="text-muted" title='JSON array of {name, type} objects. Example: [{"name":"id","type":"Int32"},{"name":"label","type":"String"}]'>
|
||||
<i class="bi bi-question-circle"></i>
|
||||
</span>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm" @bind="_formParameters"
|
||||
placeholder='e.g. [{"name":"x","type":"Int32"}]' />
|
||||
<div class="mb-3">
|
||||
<label class="form-label small">Parameters</label>
|
||||
<ParameterListEditor Json="@_formParameters" JsonChanged="@(v => _formParameters = v)" />
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label small">
|
||||
Return Definition (JSON)
|
||||
<span class="text-muted" title='JSON object with a type field. Example: {"type":"Boolean"} or {"type":"List","itemType":"Int32"}'>
|
||||
<i class="bi bi-question-circle"></i>
|
||||
</span>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm" @bind="_formReturn"
|
||||
placeholder='e.g. {"type":"Boolean"}' />
|
||||
<div class="mb-3">
|
||||
<label class="form-label small">Return value</label>
|
||||
<ReturnTypeEditor Json="@_formReturn" JsonChanged="@(v => _formReturn = v)" />
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label small">Code</label>
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user