@using System.Collections.Generic @using System.Linq @using Microsoft.JSInterop @using RolemasterDb.App.Features @implements IAsyncDisposable @inject IJSRuntime JSRuntime

Curate Result Card

@if (Model is not null) {

@Model.TableName · Column @BuildColumnDisplayText(Model) · Roll band @Model.RollBand

}
@if (IsLoading) {

Loading curation preview...

} else if (!string.IsNullOrWhiteSpace(ErrorMessage)) {

@ErrorMessage

} else if (Model is not null) {
@if (!string.IsNullOrWhiteSpace(Model.SourceImageUrl)) { @BuildSourceImageAltText(Model) } else {

No source image is available for this cell yet.

}
@{ var usedLegendEntries = GetUsedLegendEntries(Model, LegendEntries); } @if (usedLegendEntries.Count > 0) {
@foreach (var entry in usedLegendEntries) {
@entry.Symbol @entry.Label
}
}
}
@code { [Parameter, EditorRequired] public CriticalCellEditorModel? Model { get; set; } [Parameter] public bool IsLoading { get; set; } [Parameter] public bool IsSaving { get; set; } [Parameter] public string? ErrorMessage { get; set; } [Parameter] public IReadOnlyList? LegendEntries { get; set; } [Parameter, EditorRequired] public EventCallback OnClose { get; set; } [Parameter, EditorRequired] public EventCallback OnMarkCurated { get; set; } [Parameter, EditorRequired] public EventCallback OnEdit { get; set; } private IJSObjectReference? jsModule; private bool isBackdropPointerDown; protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) { return; } jsModule = await JSRuntime.InvokeAsync( "import", "./Components/Shared/CriticalCellEditorDialog.razor.js"); await jsModule.InvokeVoidAsync("lockBackgroundScroll"); } public async ValueTask DisposeAsync() { if (jsModule is null) { return; } try { await jsModule.InvokeVoidAsync("unlockBackgroundScroll"); await jsModule.DisposeAsync(); } catch (JSDisconnectedException) { } } private void HandleBackdropPointerDown() { isBackdropPointerDown = true; } private async Task HandleBackdropPointerUp() { if (!isBackdropPointerDown) { return; } isBackdropPointerDown = false; await OnClose.InvokeAsync(); } private void HandleBackdropPointerCancel() { isBackdropPointerDown = false; } private void HandleDialogPointerDown() { isBackdropPointerDown = false; } private void HandleDialogPointerUp() { isBackdropPointerDown = false; } private void HandleDialogPointerCancel() { isBackdropPointerDown = false; } private static string BuildSourceImageAltText(CriticalCellEditorModel model) { var segments = new List { 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 string BuildColumnDisplayText(CriticalCellEditorModel model) => string.IsNullOrWhiteSpace(model.GroupLabel) ? model.ColumnLabel : $"{model.GroupLabel} / {model.ColumnLabel}"; private static IReadOnlyList BuildPreviewEffects(CriticalCellEditorModel model) => model.Effects .Select(effect => new CriticalEffectLookupResponse( effect.EffectCode, effect.Target, effect.ValueInteger, effect.ValueExpression, effect.DurationRounds, effect.PerRound, effect.Modifier, effect.BodyPart, effect.IsPermanent, effect.SourceType, effect.SourceText)) .ToList(); private static IReadOnlyList BuildPreviewBranches(CriticalCellEditorModel model) => model.Branches .OrderBy(branch => branch.SortOrder) .Select(branch => new CriticalBranchLookupResponse( branch.BranchKind, branch.ConditionKey, branch.ConditionText, branch.DescriptionText, branch.RawAffixText, branch.Effects .Select(effect => new CriticalEffectLookupResponse( effect.EffectCode, effect.Target, effect.ValueInteger, effect.ValueExpression, effect.DurationRounds, effect.PerRound, effect.Modifier, effect.BodyPart, effect.IsPermanent, effect.SourceType, effect.SourceText)) .ToList(), branch.RawText, branch.SortOrder)) .ToList(); private static IReadOnlyList GetUsedLegendEntries( CriticalCellEditorModel model, IReadOnlyList? legendEntries) { if (legendEntries is null || legendEntries.Count == 0) { return []; } var usedEffectCodes = model.Effects .Select(effect => effect.EffectCode) .Concat(model.Branches.SelectMany(branch => branch.Effects.Select(effect => effect.EffectCode))) .Where(effectCode => !string.IsNullOrWhiteSpace(effectCode)) .ToHashSet(StringComparer.OrdinalIgnoreCase); return legendEntries .Where(entry => usedEffectCodes.Contains(entry.EffectCode)) .ToList(); } }