diff --git a/docs/player_gm_ux_redesign_plan.md b/docs/player_gm_ux_redesign_plan.md index 2f8ccb6..c69bef7 100644 --- a/docs/player_gm_ux_redesign_plan.md +++ b/docs/player_gm_ux_redesign_plan.md @@ -531,6 +531,10 @@ Acceptance criteria: ### Phase 2: Compact inline cell editor +Status: + +- implemented in the web app on March 15, 2026 + Scope: - remove the dedicated preview panel from the critical cell popup @@ -626,4 +630,4 @@ Mitigation: ## Recommended Next Step -Implement the new Phase 2 next. The compact inline popup editor is now the most visible remaining UX gap after the lookup flow ergonomics pass. +Implement the new Phase 3 next. The remaining structural gap is generated-versus-overridden state, so re-parse and future import refreshes can preserve intentional curation instead of treating all edited values the same. diff --git a/src/RolemasterDb.App/Components/Shared/CriticalCellEditorDialog.razor b/src/RolemasterDb.App/Components/Shared/CriticalCellEditorDialog.razor index 461717a..3aa3b53 100644 --- a/src/RolemasterDb.App/Components/Shared/CriticalCellEditorDialog.razor +++ b/src/RolemasterDb.App/Components/Shared/CriticalCellEditorDialog.razor @@ -56,34 +56,11 @@

@SaveErrorMessage

} -
-
-
-

Result Preview

-

This is the card the table browser will show.

-
-
-
-
- Severity: @Model.ColumnLabel - Roll band: @Model.RollBand - @if (!string.IsNullOrWhiteSpace(Model.GroupLabel)) - { - Variant: @Model.GroupLabel - } -
- -
-
-

Raw Text

-

Update the source text, then adjust the visible card fields below.

+

Update the source text, then correct the visible result rows below.

@@ -107,9 +84,9 @@

Base Effects

-

These chips appear on the main result.

+

Edit the badges and values that appear on the main result.

- +
@if (Model.Effects.Count == 0) { @@ -117,30 +94,15 @@ } else { -
+
@for (var index = 0; index < Model.Effects.Count; index++) { var effect = Model.Effects[index]; - var effectIndex = index; -
-
- - @GetEffectLabel(effect) -
- +
+ @InlineEffectRow(effect, () => RemoveBaseEffect(index))
}
- - @for (var index = 0; index < Model.Effects.Count; index++) - { - var effect = Model.Effects[index]; -
-
- @GetEffectLabel(effect) -
- @EffectFields(effect) -
} } @@ -149,9 +111,9 @@

Conditions

-

Use condition cards for alternate outcomes.

+

Keep alternate outcomes compact and easy to scan.

- +
@if (Model.Branches.Count == 0) { @@ -166,58 +128,45 @@
@GetBranchTitle(branch, index) -

Shown when this condition applies.

+

Shown only when this condition applies.

- +
-
- - -
-
- - +
+
+ + +
+
+ + +
Condition Effects
-

These chips only appear when the condition is met.

+

These only appear when the condition is met.

- +
+ @if (branch.Effects.Count == 0) { -

No effects on this condition card yet.

+

No effects on this condition yet.

} else { -
+
@for (var effectIndex = 0; effectIndex < branch.Effects.Count; effectIndex++) { var effect = branch.Effects[effectIndex]; - var localEffectIndex = effectIndex; -
-
- - @GetEffectLabel(effect) -
- +
+ @InlineEffectRow(effect, () => RemoveBranchEffect(branch, effectIndex))
}
- - @for (var effectIndex = 0; effectIndex < branch.Effects.Count; effectIndex++) - { - var effect = branch.Effects[effectIndex]; -
-
- @GetEffectLabel(effect) -
- @EffectFields(effect) -
- } }
@@ -545,27 +494,10 @@ !string.IsNullOrWhiteSpace(effect.SourceText) || !string.IsNullOrWhiteSpace(effect.SourceType); - private static IReadOnlyList BuildPreviewEffects(IEnumerable effects) => - effects.Select(CreatePreviewEffect).ToList(); + private static IReadOnlyList BuildSingleBadgeEffect(CriticalEffectEditorModel effect) => + [CreateBadgeEffect(effect)]; - private static IReadOnlyList BuildSinglePreviewEffect(CriticalEffectEditorModel effect) => - [CreatePreviewEffect(effect)]; - - private static IReadOnlyList BuildPreviewBranches(IEnumerable branches) => - branches - .OrderBy(branch => branch.SortOrder) - .Select(branch => new CriticalBranchLookupResponse( - branch.BranchKind, - branch.ConditionKey, - branch.ConditionText, - branch.DescriptionText, - branch.RawAffixText, - BuildPreviewEffects(branch.Effects), - branch.RawText, - branch.SortOrder)) - .ToList(); - - private static CriticalEffectLookupResponse CreatePreviewEffect(CriticalEffectEditorModel effect) => + private static CriticalEffectLookupResponse CreateBadgeEffect(CriticalEffectEditorModel effect) => new( effect.EffectCode, effect.Target, @@ -581,9 +513,12 @@ } @functions { - private RenderFragment EffectFields(CriticalEffectEditorModel effect) => @
-
-
+ private RenderFragment InlineEffectRow(CriticalEffectEditorModel effect, Action onRemove) => @
+
+
+ +
+
- @switch (effect.EffectCode) - { - case CriticalEffectCodes.DirectHits: -
- - -
- break; - case CriticalEffectCodes.StunnedRounds: - case CriticalEffectCodes.MustParryRounds: - case CriticalEffectCodes.NoParryRounds: -
- - -
- break; - case CriticalEffectCodes.BleedPerRound: -
- - -
- break; - case CriticalEffectCodes.FoePenalty: - case CriticalEffectCodes.AttackerBonusNextRound: -
- - -
- break; - case CriticalEffectCodes.PowerPointModifier: -
- - -
- break; - default: -
- - -
- break; - } + @InlineValueField(effect) @if (!string.IsNullOrWhiteSpace(effect.BodyPart)) { -
+
} - @if (!string.IsNullOrWhiteSpace(effect.Target)) + @if (ShouldShowTargetField(effect)) { -
+
}
- +
; + + private RenderFragment InlineValueField(CriticalEffectEditorModel effect) => @
+ @switch (effect.EffectCode) + { + case CriticalEffectCodes.DirectHits: + + + break; + case CriticalEffectCodes.StunnedRounds: + case CriticalEffectCodes.MustParryRounds: + case CriticalEffectCodes.NoParryRounds: + + + break; + case CriticalEffectCodes.BleedPerRound: + + + break; + case CriticalEffectCodes.FoePenalty: + case CriticalEffectCodes.AttackerBonusNextRound: + + + break; + case CriticalEffectCodes.PowerPointModifier: + + + break; + default: + + + break; + } +
; + + private static bool ShouldShowTargetField(CriticalEffectEditorModel effect) => + !string.Equals(effect.EffectCode, CriticalEffectCodes.DirectHits, StringComparison.Ordinal) && + !string.IsNullOrWhiteSpace(effect.Target); } diff --git a/src/RolemasterDb.App/wwwroot/app.css b/src/RolemasterDb.App/wwwroot/app.css index 240062d..b94ca86 100644 --- a/src/RolemasterDb.App/wwwroot/app.css +++ b/src/RolemasterDb.App/wwwroot/app.css @@ -788,21 +788,12 @@ textarea { background: rgba(252, 248, 238, 0.96); } -.critical-editor-preview-card { - display: grid; - gap: 0.85rem; -} - -.critical-editor-preview-card .critical-cell-description { - font-size: 1.05rem; -} - .critical-editor-textarea { min-height: 7rem; } .critical-editor-textarea.compact { - min-height: 4.5rem; + min-height: 3.5rem; } .critical-editor-textarea.json { @@ -810,7 +801,7 @@ textarea { } .critical-editor-textarea.tall { - min-height: 10rem; + min-height: 8rem; } .critical-editor-error { @@ -825,42 +816,56 @@ textarea { margin: 0; } -.critical-editor-chip-list { +.critical-editor-inline-list { display: grid; - gap: 0.65rem; + gap: 0.55rem; } -.critical-editor-chip-card { +.critical-editor-inline-row { + display: block; +} + +.critical-editor-effect-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; - padding: 0.65rem 0.8rem; + padding: 0.65rem 0.75rem; border-radius: 14px; background: rgba(255, 255, 255, 0.7); border: 1px solid rgba(127, 96, 55, 0.12); } -.critical-editor-chip-preview { - display: flex; - align-items: center; - gap: 0.55rem; - flex-wrap: wrap; +.critical-editor-effect-row-main { + display: grid; + gap: 0.65rem; + grid-template-columns: minmax(88px, auto) minmax(180px, 1.3fr) minmax(130px, 0.8fr); + align-items: end; + flex: 1 1 auto; +} + +.critical-editor-effect-badge { min-width: 0; } -.critical-editor-chip-preview .affix-badge-list { +.critical-editor-effect-badge .affix-badge-list { margin-top: 0; } -.critical-editor-chip-name { - font-family: var(--font-heading); - color: #5b4327; +.critical-editor-effect-kind, +.critical-editor-effect-value, +.critical-editor-effect-extra { + min-width: 0; } -.critical-editor-effect-fields { +.critical-editor-branch-line { display: grid; - gap: 0.75rem; + gap: 0.65rem; + grid-template-columns: minmax(180px, 1fr) minmax(220px, 1.4fr); +} + +.critical-editor-branch-outcome { + min-width: 0; } .critical-editor-validation-list { @@ -883,7 +888,7 @@ textarea { .critical-editor-advanced { border-radius: 18px; border: 1px solid rgba(127, 96, 55, 0.14); - background: rgba(247, 239, 225, 0.42); + background: rgba(247, 239, 225, 0.3); overflow: hidden; } @@ -912,7 +917,7 @@ textarea { .critical-editor-advanced-body { display: grid; gap: 0.85rem; - padding: 0 1rem 1rem; + padding: 0 0.9rem 0.9rem; } .critical-editor-diagnostic-grid { @@ -971,15 +976,21 @@ textarea { text-align: right; } -.critical-editor-effect-grid { - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); +.critical-editor-inline-button { + border: none; + background: transparent; + color: var(--accent); + padding: 0.2rem 0.1rem; + white-space: nowrap; } -.critical-editor-checkbox { - display: inline-flex; - align-items: center; - gap: 0.5rem; - color: #5d4429; +.critical-editor-inline-button:hover { + color: #6e4320; +} + +.critical-editor-compact-button { + padding: 0.55rem 0.9rem; + box-shadow: none; } @media (max-width: 640.98px) { @@ -1013,7 +1024,7 @@ textarea { align-items: stretch; } - .critical-editor-chip-card, + .critical-editor-effect-row, .critical-editor-card-header, .critical-editor-section-header, .critical-editor-advanced-summary, @@ -1022,6 +1033,11 @@ textarea { align-items: stretch; } + .critical-editor-effect-row-main, + .critical-editor-branch-line { + grid-template-columns: 1fr; + } + .critical-editor-diagnostic-values { justify-items: start; text-align: left;