diff --git a/apps/dashboard/src/components/pulls/detail/pull-detail-activity.tsx b/apps/dashboard/src/components/pulls/detail/pull-detail-activity.tsx index 2513974..cf05c01 100644 --- a/apps/dashboard/src/components/pulls/detail/pull-detail-activity.tsx +++ b/apps/dashboard/src/components/pulls/detail/pull-detail-activity.tsx @@ -62,6 +62,7 @@ import { groupTimelineEvents, } from "#/components/details/grouped-label-event"; import { LabelPill } from "#/components/details/label-pill"; +import { useMergeBypass } from "#/components/pulls/detail/use-merge-bypass"; import { formatRelativeTime } from "#/lib/format-relative-time"; import { deleteBranch, @@ -424,6 +425,7 @@ function MergeStatusCard({ baseRefName, canUpdateBranch, canBypassProtections, + canMerge, } = status; const approvedReviews = reviews.filter((r) => r.state === "APPROVED"); @@ -439,6 +441,17 @@ function MergeStatusCard({ const hasConflicts = mergeableState === "dirty"; const isMergeBlocked = mergeableState === "blocked" || mergeable === false; + const bypass = useMergeBypass({ + isMergeBlocked, + canBypassProtections, + hasCheckFailures, + hasReviewIssue, + hasConflicts, + isBehind, + allChecksPassed, + totalChecks: checks.total, + }); + return (
{/* Reviews section */} @@ -490,7 +503,8 @@ function MergeStatusCard({ {/* Merge action footer */} ; owner: string; repo: string; pullNumber: number; @@ -1005,7 +1021,6 @@ function MergeFooter({ "squash", ); const [isMerging, setIsMerging] = useState(false); - const [bypassChecks, setBypassChecks] = useState(false); const queryClient = useQueryClient(); const currentStrategy = @@ -1021,7 +1036,7 @@ function MergeFooter({ repo, pullNumber, mergeMethod, - bypassProtections: bypassChecks, + bypassProtections: bypass.shouldBypass, }, }); if (result.ok) { @@ -1037,7 +1052,8 @@ function MergeFooter({ } }; - const isDisabled = (isMergeBlocked && !bypassChecks) || isMerging; + const isDisabled = + !canMerge || (isMergeBlocked && !bypass.shouldBypass) || isMerging; return (
@@ -1093,18 +1109,22 @@ function MergeFooter({
- {isMergeBlocked && !bypassChecks && ( + {!canMerge ? ( +

+ You don't have permission to merge this pull request. +

+ ) : isMergeBlocked && !bypass.shouldBypass ? (

Merging is blocked — all required conditions have not been met.

- )} + ) : null} - {isMergeBlocked && canBypassProtections && ( + {bypass.showOption && (
setBypassChecks(checked === true)} + checked={bypass.checked} + onCheckedChange={(checked) => bypass.setChecked(checked === true)} />