Uh oh!
There was an error while loading. Please reload this page.
fix(web): stablize merge button with merged chip - #6271
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Your free Security trial is over. An organization admin can upgrade to Advanced for continuous pull request security review or dismiss this notice. Comment |
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a focused client-side fix that stabilizes the existing merge control and shows a confirmed merged state. Its finite per-PR state tracking and presentation logic are tested, while merge RPC behavior, schemas, and deployment remain unchanged. You can add or adjust custom eligibility rules. Learn more. |
fd4ffaa to
3c20061CompareDismissing prior approval to re-evaluate 3c20061
3c20061 to
592e3b9CompareDismissing prior approval to re-evaluate 592e3b9
592e3b9 to
23f892fCompareThere was a problem hiding this comment.
Two findings on the new pending lifecycle. The state-scoping and the awaiting-detail effect themselves look sound: pendingAction is keyed by pullRequestKey like the other panel scopes, each predicate is false in the state its action is offered from, and the manual Refresh menu item stays enabled, so the pending window cannot be wedged with no way out.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Two findings on the new pending lifecycle. The state-scoping and the awaiting-detail effect themselves look sound: pendingAction is keyed by pullRequestKey like the other panel scopes, each predicate is false in the state its action is offered from, and the manual Refresh menu item stays enabled, so the pending window cannot be wedged with no way out.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Dismissing prior approval to re-evaluate 9fdf68d
There was a problem hiding this comment.
One finding on the extended pending window introduced for merge. Everything else in the diff (per-pull-request keying of pendingAction, identity-guarded clears, the activePendingAction label read) is consistent with the panel's existing "only the pressed control speaks" contract.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
One finding on the merge-completion suppression: the header's primary control is unmounted rather than shown in a resolved state, and the suppression only lifts on a non-open detail, so a host that keeps reporting the pull request as open leaves the slot permanently empty.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
e3d9363 to
c2a2401CompareDismissing prior approval to re-evaluate c2a2401
c2a2401 to
022268eComparemaria-rcks
commented
Aug 23, 2026
pls never record the videos like that, NEVER; they make it hard to see what actually changed |
flamboh
commented
Aug 23, 2026
@maria-rcks yeah sorry you're definitely right, I'll put new ones in a sec |
flamboh
commented
Aug 23, 2026
@maria-rcks fixed, should be pretty clear now. Again, sorry. Got carried away with the Cap default edits on the vid. |
022268e to
237e0deComparefix(web): show merged state on merge button
There was a problem hiding this comment.
One finding on the new merged-button tone. The lifecycle rework itself reads consistently with the panel's contracts: the hold is per-pull-request, only the Merge control is suppressed while it is held, and detailQuery.isPending is the waiting flag of the AsyncResult (true on a refresh() refetch that already has data), so the post-merge read does arm and then clear the bound.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Bil0000
commented
Sep 1, 2026
@flamboh would be cool if you update your vid/img in the desc too 🫡 |
flamboh
commented
Sep 1, 2026
@Bil0000 working on that already! |
There was a problem hiding this comment.
The reworked hold itself checks out: useEnvironmentQuery.isPending maps to AsyncResult.waiting, so the refreshDetail() a merge takes does flip it true and then false, and observePullRequestDetail bounds the hold on that read regardless of which refresh path ran — the earlier unbounded-hold and per-PR-overwrite findings are addressed. Two findings on how the completed state is presented once it clears, inline.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
flamboh
commented
Sep 1, 2026
@Bil0000 is it intended that the "Merged" button is only shown briefly? |
Bil0000
commented
Sep 1, 2026
Change it however you like, & add some after media, will take a look then & let you know my thoughts ;) |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
flamboh
commented
Sep 1, 2026
@Bil0000 see new after video, macroscope approved as well! |
maria-rcks
commented
Sep 2, 2026
closed because of #9188 (sorry) |
flamboh
commented
Sep 2, 2026
@maria-rcks LOL no it's all good. Glad it got fixed!! |


Note
🤖 Fable 5 on behalf of Oliver
What Changed
The Merge button now stays pending until refreshed PR data confirms the merge, then becomes a solid violet "Merged" marker that persists on every merged PR, so opening one shows the outcome where the action used to be (thanks @Bil0000!). The merge success toast only fires as a fallback on hosts that confirm merges asynchronously (e.g. Azure DevOps), where the marker has to yield before the host catches up.
The action lifecycle lives in
packages/client-runtime/src/state/pullRequestActionState.tswith transitions tracked by per-PR atoms.Why
The merge command finished before the detail refresh, so stale open-state data briefly made the Merge button clickable again.
UI Changes
Before
prb_before.mp4
After
prb_after.mp4
Checklist
Built by GPT-5.6-sol (Codex CLI) and Claude Fable 5 (Claude Code) in T3 Code, with the merged-button presentation contributed by @Bil0000.
Note
Stabilize PR merge button with merged chip via shared action state
observePullRequestDetailfrom incoming detail reads.usePullRequestActionStateandpullRequestMergeButtonPresentationso PullRequestDetailPanel.tsx shows a disabled, violet-toned "Merged" chip during merge hold or once the host reports merged, and "Merging..." only while the merge is in-flight.observePullRequestDetailsees detail state leaveopenor settle open after a pending read; if the host never delivers such a read, the hold persists — verify the reconciliation logic inobservePullRequestDetail.Macroscope summarized 4ae02b4.