Separate critical editor load and save errors
This commit is contained in:
@@ -204,7 +204,8 @@
|
|||||||
Model="editorModel"
|
Model="editorModel"
|
||||||
IsLoading="isEditorLoading"
|
IsLoading="isEditorLoading"
|
||||||
IsSaving="isEditorSaving"
|
IsSaving="isEditorSaving"
|
||||||
ErrorMessage="editorError"
|
LoadErrorMessage="editorLoadError"
|
||||||
|
SaveErrorMessage="editorSaveError"
|
||||||
OnClose="CloseCellEditorAsync"
|
OnClose="CloseCellEditorAsync"
|
||||||
OnSave="SaveCellEditorAsync" />
|
OnSave="SaveCellEditorAsync" />
|
||||||
}
|
}
|
||||||
@@ -223,7 +224,8 @@
|
|||||||
private bool isEditorOpen;
|
private bool isEditorOpen;
|
||||||
private bool isEditorLoading;
|
private bool isEditorLoading;
|
||||||
private bool isEditorSaving;
|
private bool isEditorSaving;
|
||||||
private string? editorError;
|
private string? editorLoadError;
|
||||||
|
private string? editorSaveError;
|
||||||
private int? editingResultId;
|
private int? editingResultId;
|
||||||
private CriticalCellEditorModel? editorModel;
|
private CriticalCellEditorModel? editorModel;
|
||||||
|
|
||||||
@@ -321,7 +323,8 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
editorError = null;
|
editorLoadError = null;
|
||||||
|
editorSaveError = null;
|
||||||
editorModel = null;
|
editorModel = null;
|
||||||
editingResultId = resultId;
|
editingResultId = resultId;
|
||||||
isEditorSaving = false;
|
isEditorSaving = false;
|
||||||
@@ -333,7 +336,7 @@
|
|||||||
var response = await LookupService.GetCriticalCellEditorAsync(selectedTableSlug, resultId);
|
var response = await LookupService.GetCriticalCellEditorAsync(selectedTableSlug, resultId);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
editorError = "The selected cell could not be loaded for editing.";
|
editorLoadError = "The selected cell could not be loaded for editing.";
|
||||||
editorModel = null;
|
editorModel = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -342,7 +345,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
editorError = exception.Message;
|
editorLoadError = exception.Message;
|
||||||
editorModel = null;
|
editorModel = null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -356,7 +359,8 @@
|
|||||||
isEditorOpen = false;
|
isEditorOpen = false;
|
||||||
isEditorLoading = false;
|
isEditorLoading = false;
|
||||||
isEditorSaving = false;
|
isEditorSaving = false;
|
||||||
editorError = null;
|
editorLoadError = null;
|
||||||
|
editorSaveError = null;
|
||||||
editingResultId = null;
|
editingResultId = null;
|
||||||
editorModel = null;
|
editorModel = null;
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
@@ -370,14 +374,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
isEditorSaving = true;
|
isEditorSaving = true;
|
||||||
editorError = null;
|
editorSaveError = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await LookupService.UpdateCriticalCellAsync(selectedTableSlug, editingResultId.Value, editorModel.ToRequest());
|
var response = await LookupService.UpdateCriticalCellAsync(selectedTableSlug, editingResultId.Value, editorModel.ToRequest());
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
editorError = "The selected cell could not be saved.";
|
editorSaveError = "The selected cell could not be saved.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +390,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
editorError = exception.Message;
|
editorSaveError = exception.Message;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
@if (Model is not null)
|
<div class="critical-editor-backdrop" @onclick="HandleBackdropClicked">
|
||||||
{
|
<div class="critical-editor-dialog" @onclick:stopPropagation="true">
|
||||||
<div class="critical-editor-backdrop" @onclick="HandleBackdropClicked">
|
<header class="critical-editor-header">
|
||||||
<div class="critical-editor-dialog" @onclick:stopPropagation="true">
|
<div>
|
||||||
<header class="critical-editor-header">
|
<span class="eyebrow">Manual Curation</span>
|
||||||
<div>
|
@if (Model is not null)
|
||||||
<span class="eyebrow">@Model.SourceDocument</span>
|
{
|
||||||
<h3 class="panel-title">Edit @Model.TableName</h3>
|
<h3 class="panel-title">Edit @Model.TableName</h3>
|
||||||
<p class="muted critical-editor-meta">
|
<p class="muted critical-editor-meta">
|
||||||
Roll band <strong>@Model.RollBand</strong>, column <strong>@Model.ColumnLabel</strong>
|
Roll band <strong>@Model.RollBand</strong>, column <strong>@Model.ColumnLabel</strong>
|
||||||
@@ -13,177 +13,187 @@
|
|||||||
<span>, group <strong>@Model.GroupLabel</strong></span>
|
<span>, group <strong>@Model.GroupLabel</strong></span>
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
}
|
||||||
<button type="button" class="btn btn-link critical-editor-close" @onclick="OnClose">Close</button>
|
else
|
||||||
</header>
|
{
|
||||||
|
<h3 class="panel-title">Critical Cell Editor</h3>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-link critical-editor-close" @onclick="OnClose">Close</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
@if (IsLoading)
|
@if (IsLoading)
|
||||||
{
|
{
|
||||||
|
<div class="critical-editor-body">
|
||||||
|
<p class="muted">Loading editor...</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else if (!string.IsNullOrWhiteSpace(LoadErrorMessage))
|
||||||
|
{
|
||||||
|
<div class="critical-editor-body">
|
||||||
|
<p class="error-text critical-editor-error">@LoadErrorMessage</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else if (Model is not null)
|
||||||
|
{
|
||||||
|
<EditForm Model="Model" OnSubmit="HandleSubmitAsync" class="critical-editor-form">
|
||||||
<div class="critical-editor-body">
|
<div class="critical-editor-body">
|
||||||
<p class="muted">Loading editor...</p>
|
@if (!string.IsNullOrWhiteSpace(SaveErrorMessage))
|
||||||
</div>
|
{
|
||||||
}
|
<p class="error-text critical-editor-error">@SaveErrorMessage</p>
|
||||||
else
|
}
|
||||||
{
|
|
||||||
<EditForm Model="Model" OnSubmit="HandleSubmitAsync" class="critical-editor-form">
|
<section class="critical-editor-section">
|
||||||
<div class="critical-editor-body">
|
<h4>Base Cell</h4>
|
||||||
@if (!string.IsNullOrWhiteSpace(ErrorMessage))
|
<div class="field-shell">
|
||||||
|
<label>Raw Cell Text</label>
|
||||||
|
<InputTextArea class="input-shell critical-editor-textarea tall" @bind-Value="Model.RawCellText" />
|
||||||
|
</div>
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Description / Prose</label>
|
||||||
|
<InputText class="input-shell" @bind-Value="Model.DescriptionText" />
|
||||||
|
</div>
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Affix Text</label>
|
||||||
|
<InputText class="input-shell" @bind-Value="Model.RawAffixText" />
|
||||||
|
</div>
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Parse Status</label>
|
||||||
|
<InputText class="input-shell" @bind-Value="Model.ParseStatus" />
|
||||||
|
</div>
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Parsed Json</label>
|
||||||
|
<InputTextArea class="input-shell critical-editor-textarea json" @bind-Value="Model.ParsedJson" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="critical-editor-section">
|
||||||
|
<div class="critical-editor-section-header">
|
||||||
|
<h4>Base Effects</h4>
|
||||||
|
<button type="button" class="btn-ritual" @onclick="AddBaseEffect">Add Effect</button>
|
||||||
|
</div>
|
||||||
|
@if (Model.Effects.Count == 0)
|
||||||
{
|
{
|
||||||
<p class="error-text critical-editor-error">@ErrorMessage</p>
|
<p class="muted">No normalized base effects for this cell.</p>
|
||||||
}
|
}
|
||||||
|
else
|
||||||
<section class="critical-editor-section">
|
{
|
||||||
<h4>Base Cell</h4>
|
@for (var index = 0; index < Model.Effects.Count; index++)
|
||||||
<div class="field-shell">
|
|
||||||
<label>Raw Cell Text</label>
|
|
||||||
<InputTextArea class="input-shell critical-editor-textarea tall" @bind-Value="Model.RawCellText" />
|
|
||||||
</div>
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Description / Prose</label>
|
|
||||||
<InputText class="input-shell" @bind-Value="Model.DescriptionText" />
|
|
||||||
</div>
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Affix Text</label>
|
|
||||||
<InputText class="input-shell" @bind-Value="Model.RawAffixText" />
|
|
||||||
</div>
|
|
||||||
<div class="form-grid">
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Parse Status</label>
|
|
||||||
<InputText class="input-shell" @bind-Value="Model.ParseStatus" />
|
|
||||||
</div>
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Parsed Json</label>
|
|
||||||
<InputTextArea class="input-shell critical-editor-textarea json" @bind-Value="Model.ParsedJson" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="critical-editor-section">
|
|
||||||
<div class="critical-editor-section-header">
|
|
||||||
<h4>Base Effects</h4>
|
|
||||||
<button type="button" class="btn-ritual" @onclick="AddBaseEffect">Add Effect</button>
|
|
||||||
</div>
|
|
||||||
@if (Model.Effects.Count == 0)
|
|
||||||
{
|
{
|
||||||
<p class="muted">No normalized base effects for this cell.</p>
|
var effect = Model.Effects[index];
|
||||||
}
|
<div class="critical-editor-card">
|
||||||
else
|
<div class="critical-editor-card-header">
|
||||||
{
|
<strong>Effect @(index + 1)</strong>
|
||||||
@for (var index = 0; index < Model.Effects.Count; index++)
|
<button type="button" class="btn btn-link" @onclick="() => RemoveBaseEffect(index)">Remove</button>
|
||||||
{
|
|
||||||
var effect = Model.Effects[index];
|
|
||||||
<div class="critical-editor-card">
|
|
||||||
<div class="critical-editor-card-header">
|
|
||||||
<strong>Effect @(index + 1)</strong>
|
|
||||||
<button type="button" class="btn btn-link" @onclick="() => RemoveBaseEffect(index)">Remove</button>
|
|
||||||
</div>
|
|
||||||
@EffectFields(effect)
|
|
||||||
</div>
|
</div>
|
||||||
}
|
@EffectFields(effect)
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</section>
|
}
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="critical-editor-section">
|
<section class="critical-editor-section">
|
||||||
<div class="critical-editor-section-header">
|
<div class="critical-editor-section-header">
|
||||||
<h4>Branches</h4>
|
<h4>Branches</h4>
|
||||||
<button type="button" class="btn-ritual" @onclick="AddBranch">Add Branch</button>
|
<button type="button" class="btn-ritual" @onclick="AddBranch">Add Branch</button>
|
||||||
</div>
|
</div>
|
||||||
@if (Model.Branches.Count == 0)
|
@if (Model.Branches.Count == 0)
|
||||||
|
{
|
||||||
|
<p class="muted">No branch records on this cell.</p>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@for (var index = 0; index < Model.Branches.Count; index++)
|
||||||
{
|
{
|
||||||
<p class="muted">No branch records on this cell.</p>
|
var branch = Model.Branches[index];
|
||||||
}
|
<div class="critical-editor-card branch-card-editor">
|
||||||
else
|
<div class="critical-editor-card-header">
|
||||||
{
|
<strong>Branch @(index + 1)</strong>
|
||||||
@for (var index = 0; index < Model.Branches.Count; index++)
|
<button type="button" class="btn btn-link" @onclick="() => RemoveBranch(index)">Remove</button>
|
||||||
{
|
</div>
|
||||||
var branch = Model.Branches[index];
|
<div class="form-grid">
|
||||||
<div class="critical-editor-card branch-card-editor">
|
<div class="field-shell">
|
||||||
<div class="critical-editor-card-header">
|
<label>Branch Kind</label>
|
||||||
<strong>Branch @(index + 1)</strong>
|
<InputText class="input-shell" @bind-Value="branch.BranchKind" />
|
||||||
<button type="button" class="btn btn-link" @onclick="() => RemoveBranch(index)">Remove</button>
|
|
||||||
</div>
|
|
||||||
<div class="form-grid">
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Branch Kind</label>
|
|
||||||
<InputText class="input-shell" @bind-Value="branch.BranchKind" />
|
|
||||||
</div>
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Condition Key</label>
|
|
||||||
<InputText class="input-shell" @bind-Value="branch.ConditionKey" />
|
|
||||||
</div>
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Sort Order</label>
|
|
||||||
<InputNumber TValue="int" class="input-shell" @bind-Value="branch.SortOrder" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="field-shell">
|
<div class="field-shell">
|
||||||
<label>Condition Text</label>
|
<label>Condition Key</label>
|
||||||
<InputText class="input-shell" @bind-Value="branch.ConditionText" />
|
<InputText class="input-shell" @bind-Value="branch.ConditionKey" />
|
||||||
</div>
|
</div>
|
||||||
<div class="field-shell">
|
<div class="field-shell">
|
||||||
<label>Raw Text</label>
|
<label>Sort Order</label>
|
||||||
<InputTextArea class="input-shell critical-editor-textarea" @bind-Value="branch.RawText" />
|
<InputNumber TValue="int" class="input-shell" @bind-Value="branch.SortOrder" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Condition Text</label>
|
||||||
|
<InputText class="input-shell" @bind-Value="branch.ConditionText" />
|
||||||
|
</div>
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Raw Text</label>
|
||||||
|
<InputTextArea class="input-shell critical-editor-textarea" @bind-Value="branch.RawText" />
|
||||||
|
</div>
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Description / Prose</label>
|
||||||
|
<InputText class="input-shell" @bind-Value="branch.DescriptionText" />
|
||||||
|
</div>
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Affix Text</label>
|
||||||
|
<InputText class="input-shell" @bind-Value="branch.RawAffixText" />
|
||||||
|
</div>
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="field-shell">
|
||||||
|
<label>Condition Json</label>
|
||||||
|
<InputTextArea class="input-shell critical-editor-textarea compact" @bind-Value="branch.ConditionJson" />
|
||||||
</div>
|
</div>
|
||||||
<div class="field-shell">
|
<div class="field-shell">
|
||||||
<label>Description / Prose</label>
|
<label>Parsed Json</label>
|
||||||
<InputText class="input-shell" @bind-Value="branch.DescriptionText" />
|
<InputTextArea class="input-shell critical-editor-textarea json" @bind-Value="branch.ParsedJson" />
|
||||||
</div>
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Affix Text</label>
|
|
||||||
<InputText class="input-shell" @bind-Value="branch.RawAffixText" />
|
|
||||||
</div>
|
|
||||||
<div class="form-grid">
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Condition Json</label>
|
|
||||||
<InputTextArea class="input-shell critical-editor-textarea compact" @bind-Value="branch.ConditionJson" />
|
|
||||||
</div>
|
|
||||||
<div class="field-shell">
|
|
||||||
<label>Parsed Json</label>
|
|
||||||
<InputTextArea class="input-shell critical-editor-textarea json" @bind-Value="branch.ParsedJson" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="critical-editor-subsection">
|
<div class="critical-editor-subsection">
|
||||||
<div class="critical-editor-section-header">
|
<div class="critical-editor-section-header">
|
||||||
<h5>Branch Effects</h5>
|
<h5>Branch Effects</h5>
|
||||||
<button type="button" class="btn-ritual" @onclick="() => AddBranchEffect(branch)">Add Effect</button>
|
<button type="button" class="btn-ritual" @onclick="() => AddBranchEffect(branch)">Add Effect</button>
|
||||||
</div>
|
</div>
|
||||||
@if (branch.Effects.Count == 0)
|
@if (branch.Effects.Count == 0)
|
||||||
|
{
|
||||||
|
<p class="muted">No normalized branch effects.</p>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@for (var effectIndex = 0; effectIndex < branch.Effects.Count; effectIndex++)
|
||||||
{
|
{
|
||||||
<p class="muted">No normalized branch effects.</p>
|
var effect = branch.Effects[effectIndex];
|
||||||
}
|
<div class="critical-editor-card nested">
|
||||||
else
|
<div class="critical-editor-card-header">
|
||||||
{
|
<strong>Branch Effect @(effectIndex + 1)</strong>
|
||||||
@for (var effectIndex = 0; effectIndex < branch.Effects.Count; effectIndex++)
|
<button type="button" class="btn btn-link" @onclick="() => RemoveBranchEffect(branch, effectIndex)">Remove</button>
|
||||||
{
|
|
||||||
var effect = branch.Effects[effectIndex];
|
|
||||||
<div class="critical-editor-card nested">
|
|
||||||
<div class="critical-editor-card-header">
|
|
||||||
<strong>Branch Effect @(effectIndex + 1)</strong>
|
|
||||||
<button type="button" class="btn btn-link" @onclick="() => RemoveBranchEffect(branch, effectIndex)">Remove</button>
|
|
||||||
</div>
|
|
||||||
@EffectFields(effect)
|
|
||||||
</div>
|
</div>
|
||||||
}
|
@EffectFields(effect)
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
</div>
|
||||||
}
|
}
|
||||||
</section>
|
}
|
||||||
</div>
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
<footer class="critical-editor-footer">
|
<footer class="critical-editor-footer">
|
||||||
<button type="button" class="btn btn-link" @onclick="OnClose" disabled="@IsSaving">Cancel</button>
|
<button type="button" class="btn btn-link" @onclick="OnClose" disabled="@IsSaving">Cancel</button>
|
||||||
<button type="submit" class="btn-ritual" disabled="@IsSaving">
|
<button type="submit" class="btn-ritual" disabled="@IsSaving">
|
||||||
@(IsSaving ? "Saving..." : "Save Cell")
|
@(IsSaving ? "Saving..." : "Save Cell")
|
||||||
</button>
|
</button>
|
||||||
</footer>
|
</footer>
|
||||||
</EditForm>
|
</EditForm>
|
||||||
}
|
}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter, EditorRequired]
|
[Parameter, EditorRequired]
|
||||||
@@ -196,7 +206,10 @@
|
|||||||
public bool IsSaving { get; set; }
|
public bool IsSaving { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string? ErrorMessage { get; set; }
|
public string? LoadErrorMessage { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string? SaveErrorMessage { get; set; }
|
||||||
|
|
||||||
[Parameter, EditorRequired]
|
[Parameter, EditorRequired]
|
||||||
public EventCallback OnClose { get; set; }
|
public EventCallback OnClose { get; set; }
|
||||||
|
|||||||
Reference in New Issue
Block a user