Show critical curation state in the editor and tables

This commit is contained in:
2026-03-17 22:29:05 +01:00
parent 9d25304a27
commit 14bd666f43
4 changed files with 174 additions and 5 deletions

View File

@@ -121,12 +121,14 @@
@if (TryGetCell(rollBand.Label, group.Key, column.Key, out var groupedCell))
{
<td
class="critical-table-cell is-editable"
class="@GetCellCssClass(groupedCell)"
tabindex="0"
title="Click to edit this cell"
title="@GetCellTitle(groupedCell)"
aria-label="@GetCellTitle(groupedCell)"
@onclick="() => OpenCellEditorAsync(groupedCell.ResultId)"
@onkeydown="args => HandleCellKeyDownAsync(args, groupedCell.ResultId)">
<CompactCriticalCell
IsCurated="@groupedCell.IsCurated"
Description="@(groupedCell.Description ?? string.Empty)"
Effects="@(groupedCell.Effects ?? Array.Empty<CriticalEffectLookupResponse>())"
Branches="@(groupedCell.Branches ?? Array.Empty<CriticalBranchLookupResponse>())" />
@@ -148,12 +150,14 @@
@if (TryGetCell(rollBand.Label, null, column.Key, out var cell))
{
<td
class="critical-table-cell is-editable"
class="@GetCellCssClass(cell)"
tabindex="0"
title="Click to edit this cell"
title="@GetCellTitle(cell)"
aria-label="@GetCellTitle(cell)"
@onclick="() => OpenCellEditorAsync(cell.ResultId)"
@onkeydown="args => HandleCellKeyDownAsync(args, cell.ResultId)">
<CompactCriticalCell
IsCurated="@cell.IsCurated"
Description="@(cell.Description ?? string.Empty)"
Effects="@(cell.Effects ?? Array.Empty<CriticalEffectLookupResponse>())"
Branches="@(cell.Branches ?? Array.Empty<CriticalBranchLookupResponse>())" />
@@ -457,4 +461,14 @@
await OpenCellEditorAsync(resultId);
}
}
private static string GetCellCssClass(CriticalTableCellDetail cell) =>
cell.IsCurated
? "critical-table-cell is-editable is-curated"
: "critical-table-cell is-editable needs-curation";
private static string GetCellTitle(CriticalTableCellDetail cell) =>
cell.IsCurated
? "Curated cell. Click to edit this cell."
: "Needs curation. Click to edit this cell.";
}

View File

@@ -2,6 +2,12 @@
@using RolemasterDb.App.Features
<div class="critical-cell">
<div class="critical-cell-status-row">
<span class="critical-cell-status-chip @(IsCurated ? "is-curated" : "needs-curation")">
@(IsCurated ? "Curated" : "Needs Curation")
</span>
</div>
@if (!string.IsNullOrWhiteSpace(Description))
{
<p class="critical-cell-description">@Description</p>
@@ -40,6 +46,9 @@
[Parameter, EditorRequired]
public string Description { get; set; } = string.Empty;
[Parameter]
public bool IsCurated { get; set; }
[Parameter]
public IReadOnlyList<CriticalEffectLookupResponse>? Effects { get; set; }

View File

@@ -32,6 +32,15 @@
<span> · Variant <strong>@Model.GroupLabel</strong></span>
}
</p>
<div class="critical-editor-status-row">
<span class="critical-editor-curation-badge @(Model.IsCurated ? "is-curated" : "needs-curation")">
@(Model.IsCurated ? "Curated" : "Needs Curation")
</span>
@if (Model.SourcePageNumber is not null)
{
<span class="chip">Source page @Model.SourcePageNumber</span>
}
</div>
}
else
{
@@ -67,6 +76,47 @@
<p class="error-text critical-editor-error">@SaveErrorMessage</p>
}
<section class="critical-editor-source-grid">
<div class="critical-editor-card critical-editor-status-card">
<div class="critical-editor-section-header">
<div>
<h4>Curation State</h4>
<p class="muted">Curated cells are protected from importer content overwrites until you unmark them.</p>
</div>
</div>
<label class="critical-editor-curation-toggle">
<InputCheckbox @bind-Value="Model.IsCurated" />
<span>Mark this result curated</span>
</label>
<p class="muted critical-editor-inline-copy">
@(Model.IsCurated
? "This result will keep its current text, branches, and effects on later imports."
: "This result will be refreshed from the importer on later imports.")
</p>
</div>
<div class="critical-editor-card critical-editor-source-card">
<div class="critical-editor-section-header">
<div>
<h4>Source Cell</h4>
<p class="muted">Use the importer crop as a visual reference while curating the result.</p>
</div>
</div>
@if (!string.IsNullOrWhiteSpace(Model.SourceImageUrl))
{
<img
class="critical-editor-source-image"
src="@Model.SourceImageUrl"
alt="@BuildSourceImageAltText(Model)" />
}
else
{
<p class="muted critical-editor-inline-copy">No source image is available for this cell yet.</p>
}
</div>
</section>
<section class="critical-editor-section">
<div class="critical-editor-section-header">
<div>
@@ -692,6 +742,23 @@
? "This is the result that will be saved."
: "This is the edited card before the last re-parse.";
private static string BuildSourceImageAltText(CriticalCellEditorModel model)
{
var segments = new List<string>
{
model.TableName,
$"roll band {model.RollBand}",
$"column {model.ColumnLabel}"
};
if (!string.IsNullOrWhiteSpace(model.GroupLabel))
{
segments.Add($"variant {model.GroupLabel}");
}
return string.Join(", ", segments);
}
private static IReadOnlyList<CriticalEffectLookupResponse> BuildPreviewEffects(CriticalCellEditorModel model) =>
model.Effects
.Select(CreatePreviewEffect)