Mergeability wording: "Able to be Merged" in green; simplified soft-red phrases for every blocked state #588

Closed
opened 2026-09-15 18:15:12 +00:00 by crueber · 1 comment
Owner

Mergeability wording: "Able to be Merged" in green, simplified soft-red phrases for every blocked state

What's requested

The PR page's mergeability surfaces currently print the internal state machine's raw words in plain text. Simplify the user-visible wording following the #561 pattern: one shared display helper maps internal/merge state to human phrases plus a tone, with green for mergeable and soft red for every blocked state.

Proposed phrase set (tone noted):

Green (mergeable):

  • clean → Able to be Merged
  • behind → Able to be Merged, with "branch is behind — update" as secondary detail (behind stays mergeable per the 08 §2 machine; the update-branch button already covers remediation)

Soft red (blocked):

  • draft → Draft pull request
  • failing required checks → Checks failing
  • CHANGES_REQUESTED → Changes requested
  • dirty → Merge conflicts (keep the conflicting-file detail as secondary text or tooltip, not in the headline phrase)
  • zero required checks configured → No checks required (see web/src/lib/checks-empty.js — treat per its existing semantics; implementer's call whether it's neutral or red, noted in the PR)

Neutral (not blocked, not mergeable):

  • ready (mergeability data still loading) → Checking mergeability
  • merging → Merging…
  • failed (merge task) → Merge failed (task error detail stays in the existing task line)
  • already merged (up_to_date) → Already merged
  • unknown/missing → pass through or a neutral "Unknown", implementer's call, noted in the PR

"Soft red" = the muted red the app already uses for warnings on this page (text-red-600 dark:text-red-400 or the chip-closed red); green = the emerald family (chip-open / text-emerald-600 dark:text-emerald-400). Tailwind utilities only, no ad-hoc CSS.

Evidence (static read)

  • web/src/components/MergeBox.jsx:164 — <p class="text-sm">{state()}</p> renders the raw internal state word (draft | blocked | mergeable | ready | merging | failed) with no color and no phrase mapping. Users see "blocked" with nothing else on that line; the reasons live in a separate amber line (lines 194-197, "blocking merge: …").
  • web/src/components/MergeBox.jsx:36-44 — mergeState() is the internal machine (08 §2); its return values are implementation vocabulary, not UI copy.
  • web/src/pages/Pull.jsx:59-73 — mergeableText() prints "mergeable", "mergeable (behind)", "conflicts: file, file", "already merged", "checking…" as plain unstyled text in the sidebar.
  • web/src/pages/Pull.jsx:1384 — that sidebar value line: <p class="text-sm">{mergeableText(mergeable())}</p>.

Two render sites, two inconsistent vocabularies ("mergeable" vs "mergeable" as a machine state, "conflicts: …" vs "blocked"), neither colored, neither phrased for humans.

Architecture notes

  • Extend the #561 precedent: web/src/lib/pull-state.js is the established home for pure PR display helpers (reviewVerdictLabel at line 112, headless-testable via node --test). Add one helper, e.g. mergeabilityDisplay(state, detail) → { text, tone } or { text, cls }, covering every internal mergeState value AND every mergeable.state value.
  • Internal values (mergeState returns, mergeable.state wire values from the API) stay byte-identical — this is display mapping only, mirroring how #561 kept review wire values untouched. MergeBox's chip-free design means the helper likely returns Tailwind text classes rather than chip classes.
  • Apply at BOTH sites: MergeBox's state line (MergeBox.jsx:164) and the sidebar Mergeability value (Pull.jsx:1384 via mergeableText). Keep the existing amber "blocking merge: …" reasons line (MergeBox.jsx:194-197) — it carries the detail; the headline phrase carries the state.
  • tooltip (MergeBox.jsx:77-85) may keep machine wording for debugging, implementer's call.

Acceptance criteria

  • One shared helper in web/src/lib/pull-state.js maps every state above to {phrase, tone}; no per-callsite ternaries at either render site.
  • MergeBox state line (MergeBox.jsx:164) shows "Able to be Merged" in green when mergeable, a short soft-red phrase for each blocked state, neutral phrases otherwise — never the raw machine word ("blocked", "ready").
  • Sidebar Mergeability value (Pull.jsx:1384) uses the same helper — same phrase, same color — replacing mergeableText's raw vocabulary.
  • All five blocked conditions covered: draft, failing checks, changes requested, conflicts, plus the zero-checks case decided explicitly and noted.
  • Wire/internal state values unchanged: mergeState returns, mergeable.state API values, state comparisons, and the merge button's enable logic (enabled(), MergeBox.jsx:76) untouched.
  • node --test covers the helper (every known value + unknown passthrough).
  • Render verification: headless DOM assertions (or screenshot review) on the PR page confirming the green/soft-red rendering before close — no close on code reading alone.
# Mergeability wording: "Able to be Merged" in green, simplified soft-red phrases for every blocked state ## What's requested The PR page's mergeability surfaces currently print the internal state machine's raw words in plain text. Simplify the user-visible wording following the #561 pattern: one shared display helper maps internal/merge state to human phrases plus a tone, with green for mergeable and soft red for every blocked state. Proposed phrase set (tone noted): **Green (mergeable):** - clean → **Able to be Merged** - behind → Able to be Merged, with "branch is behind — update" as secondary detail (behind stays mergeable per the 08 §2 machine; the update-branch button already covers remediation) **Soft red (blocked):** - draft → Draft pull request - failing required checks → Checks failing - `CHANGES_REQUESTED` → Changes requested - `dirty` → Merge conflicts (keep the conflicting-file detail as secondary text or tooltip, not in the headline phrase) - zero required checks configured → No checks required (see `web/src/lib/checks-empty.js` — treat per its existing semantics; implementer's call whether it's neutral or red, noted in the PR) **Neutral (not blocked, not mergeable):** - ready (mergeability data still loading) → Checking mergeability - merging → Merging… - failed (merge task) → Merge failed (task error detail stays in the existing task line) - already merged (`up_to_date`) → Already merged - unknown/missing → pass through or a neutral "Unknown", implementer's call, noted in the PR "Soft red" = the muted red the app already uses for warnings on this page (`text-red-600 dark:text-red-400` or the `chip-closed` red); green = the emerald family (`chip-open` / `text-emerald-600 dark:text-emerald-400`). Tailwind utilities only, no ad-hoc CSS. ## Evidence (static read) - `web/src/components/MergeBox.jsx:164` — `<p class="text-sm">{state()}</p>` renders the raw internal state word (`draft` | `blocked` | `mergeable` | `ready` | `merging` | `failed`) with no color and no phrase mapping. Users see "blocked" with nothing else on that line; the reasons live in a separate amber line (lines 194-197, "blocking merge: …"). - `web/src/components/MergeBox.jsx:36-44` — `mergeState()` is the internal machine (08 §2); its return values are implementation vocabulary, not UI copy. - `web/src/pages/Pull.jsx:59-73` — `mergeableText()` prints "mergeable", "mergeable (behind)", "conflicts: file, file", "already merged", "checking…" as plain unstyled text in the sidebar. - `web/src/pages/Pull.jsx:1384` — that sidebar value line: `<p class="text-sm">{mergeableText(mergeable())}</p>`. Two render sites, two inconsistent vocabularies ("mergeable" vs "mergeable" as a machine state, "conflicts: …" vs "blocked"), neither colored, neither phrased for humans. ## Architecture notes - Extend the #561 precedent: `web/src/lib/pull-state.js` is the established home for pure PR display helpers (`reviewVerdictLabel` at line 112, headless-testable via node --test). Add one helper, e.g. `mergeabilityDisplay(state, detail)` → `{ text, tone }` or `{ text, cls }`, covering every internal mergeState value AND every `mergeable.state` value. - Internal values (`mergeState` returns, `mergeable.state` wire values from the API) stay byte-identical — this is display mapping only, mirroring how #561 kept review wire values untouched. `MergeBox`'s chip-free design means the helper likely returns Tailwind text classes rather than chip classes. - Apply at BOTH sites: MergeBox's state line (MergeBox.jsx:164) and the sidebar Mergeability value (Pull.jsx:1384 via `mergeableText`). Keep the existing amber "blocking merge: …" reasons line (MergeBox.jsx:194-197) — it carries the detail; the headline phrase carries the state. - `tooltip` (MergeBox.jsx:77-85) may keep machine wording for debugging, implementer's call. ## Acceptance criteria - [ ] One shared helper in `web/src/lib/pull-state.js` maps every state above to {phrase, tone}; no per-callsite ternaries at either render site. - [ ] MergeBox state line (MergeBox.jsx:164) shows "Able to be Merged" in green when mergeable, a short soft-red phrase for each blocked state, neutral phrases otherwise — never the raw machine word ("blocked", "ready"). - [ ] Sidebar Mergeability value (Pull.jsx:1384) uses the same helper — same phrase, same color — replacing `mergeableText`'s raw vocabulary. - [ ] All five blocked conditions covered: draft, failing checks, changes requested, conflicts, plus the zero-checks case decided explicitly and noted. - [ ] Wire/internal state values unchanged: `mergeState` returns, `mergeable.state` API values, state comparisons, and the merge button's enable logic (`enabled()`, MergeBox.jsx:76) untouched. - [ ] node --test covers the helper (every known value + unknown passthrough). - [ ] Render verification: headless DOM assertions (or screenshot review) on the PR page confirming the green/soft-red rendering before close — no close on code reading alone.
crueber added this to the v1 milestone 2026-09-15 18:15:42 +00:00
Author
Owner

Fixed by #591 (merged): shared mergeabilityDisplay helper in pull-state.js ({text, cls, sub}) applied at both MergeBox state line and sidebar — Able to be Merged in green, soft-red blocked phrases, neutral otherwise; zero-checks reads No checks required in neutral zinc; wire/machine values and enable logic untouched. Verified: 1481 unit tests green (smoke excluded, pre-existing), vite/esbuild green, independent review APPROVE with both state sets enumerated gap-free.

Fixed by #591 (merged): shared mergeabilityDisplay helper in pull-state.js ({text, cls, sub}) applied at both MergeBox state line and sidebar — Able to be Merged in green, soft-red blocked phrases, neutral otherwise; zero-checks reads No checks required in neutral zinc; wire/machine values and enable logic untouched. Verified: 1481 unit tests green (smoke excluded, pre-existing), vite/esbuild green, independent review APPROVE with both state sets enumerated gap-free.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
crueber/walhub#588
No description provided.