| ... | ... | @@ -147,6 +147,12 @@ const ACTION_SUCCESS_LABELS: Record<PullRequestAction, string> = { |
| 147 | 147 | "disable-auto-merge": "Auto-merge turned off", |
| 148 | 148 | }; |
| 149 | 149 | |
| 150 | const MERGE_METHOD_LABELS: Record<PullRequestMergeMethod, string> = { |
| 151 | merge: "Merge", |
| 152 | squash: "Squash", |
| 153 | rebase: "Rebase", |
| 154 | }; |
| 155 | |
| 150 | 156 | /** Said as the thing that did not happen, rather than as the operation that returned an error. */ |
| 151 | 157 | const ACTION_FAILURE_LABELS: Record<PullRequestAction, string> = { |
| 152 | 158 | merge: "Could not merge this pull request", |
| ... | ... | @@ -460,9 +466,11 @@ export function PullRequestDetailPanel({ |
| 460 | 466 | if (scroller) scroller.scrollTop = Math.max(0, scroller.scrollTop + delta); |
| 461 | 467 | }, [condensed]); |
| 462 | 468 | const [mergeMethod, setMergeMethod] = useState<PullRequestMergeMethod>("merge"); |
| 463 | | const [confirmAction, setConfirmAction] = useState< |
| 464 | | "merge" | "close" | "enable-auto-merge" | null |
| 465 | | >(null); |
| 469 | const [confirmation, setConfirmation] = useState<{ |
| 470 | readonly open: boolean; |
| 471 | readonly action: "merge" | "close" | "enable-auto-merge"; |
| 472 | }>({ open: false, action: "merge" }); |
| 473 | const confirmAction = confirmation.action; |
| 466 | 474 | // Which handoff is preparing, keyed so a per-finding button can say "Preparing..." on itself |
| 467 | 475 | // alone. One at a time whatever the key: they all check the same pull request out. |
| 468 | 476 | const [handoff, setHandoff] = useState<string | null>(null); |
| ... | ... | @@ -1013,6 +1021,7 @@ export function PullRequestDetailPanel({ |
| 1013 | 1021 | const selectedMergeMethod = allowedMergeMethods.includes(mergeMethod) |
| 1014 | 1022 | ? mergeMethod |
| 1015 | 1023 | : (allowedMergeMethods[0] ?? "merge"); |
| 1024 | const selectedMergeMethodLabel = MERGE_METHOD_LABELS[selectedMergeMethod]; |
| 1016 | 1025 | const conflicting = detail?.state === "open" && detail.mergeability === "conflicting"; |
| 1017 | 1026 | // Only an outright yes arms it. A host that reports nothing has not said the merge is already |
| 1018 | 1027 | // spoken for, and an off switch for something that may not be on says the wrong thing twice. |
| ... | ... | @@ -1297,7 +1306,9 @@ export function PullRequestDetailPanel({ |
| 1297 | 1306 | allowedMergeMethods.length > 0 ? ( |
| 1298 | 1307 | <MenuItem |
| 1299 | 1308 | disabled={actionPending} |
| 1300 | | onClick={() => setConfirmAction("enable-auto-merge")} |
| 1309 | onClick={() => |
| 1310 | setConfirmation({ open: true, action: "enable-auto-merge" }) |
| 1311 | } |
| 1301 | 1312 | > |
| 1302 | 1313 | <GitMergeIcon className="size-3.5" /> |
| 1303 | 1314 | Enable auto-merge |
| ... | ... | @@ -1326,7 +1337,7 @@ export function PullRequestDetailPanel({ |
| 1326 | 1337 | icon and the label need their own row to share a line. */} |
| 1327 | 1338 | <span className="flex min-w-0 items-center gap-2"> |
| 1328 | 1339 | <GitMergeIcon className="size-3.5" /> |
| 1329 | | <span className="capitalize">{method}</span> |
| 1340 | <span>{MERGE_METHOD_LABELS[method]}</span> |
| 1330 | 1341 | </span> |
| 1331 | 1342 | </MenuRadioItem> |
| 1332 | 1343 | ))} |
| ... | ... | @@ -1363,7 +1374,7 @@ export function PullRequestDetailPanel({ |
| 1363 | 1374 | <MenuItem |
| 1364 | 1375 | variant="destructive" |
| 1365 | 1376 | disabled={actionPending} |
| 1366 | | onClick={() => setConfirmAction("close")} |
| 1377 | onClick={() => setConfirmation({ open: true, action: "close" })} |
| 1367 | 1378 | > |
| 1368 | 1379 | <GitPullRequestClosedIcon className="size-3.5" /> |
| 1369 | 1380 | Close pull request |
| ... | ... | @@ -1461,9 +1472,9 @@ export function PullRequestDetailPanel({ |
| 1461 | 1472 | <Button |
| 1462 | 1473 | size="xs" |
| 1463 | 1474 | disabled={actionPending} |
| 1464 | | onClick={() => setConfirmAction("merge")} |
| 1475 | onClick={() => setConfirmation({ open: true, action: "merge" })} |
| 1465 | 1476 | > |
| 1466 | | {pendingAction === "merge" ? "Merging..." : "Merge"} |
| 1477 | {pendingAction === "merge" ? "Merging..." : selectedMergeMethodLabel} |
| 1467 | 1478 | </Button> |
| 1468 | 1479 | ) : null} |
| 1469 | 1480 | </> |
| ... | ... | @@ -1980,8 +1991,11 @@ export function PullRequestDetailPanel({ |
| 1980 | 1991 | </div> |
| 1981 | 1992 | |
| 1982 | 1993 | <AlertDialog |
| 1983 | | open={confirmAction !== null} |
| 1984 | | onOpenChange={(open) => !open && setConfirmAction(null)} |
| 1994 | open={confirmation.open} |
| 1995 | onOpenChange={(open) => setConfirmation((current) => ({ ...current, open }))} |
| 1996 | onOpenChangeComplete={(open) => { |
| 1997 | if (!open) setConfirmation({ open: false, action: "merge" }); |
| 1998 | }} |
| 1985 | 1999 | > |
| 1986 | 2000 | <AlertDialogPopup> |
| 1987 | 2001 | <AlertDialogHeader> |
| ... | ... | @@ -2013,7 +2027,7 @@ export function PullRequestDetailPanel({ |
| 2013 | 2027 | disabled={actionPending} |
| 2014 | 2028 | onClick={() => { |
| 2015 | 2029 | const action = confirmAction; |
| 2016 | | setConfirmAction(null); |
| 2030 | setConfirmation((current) => ({ ...current, open: false })); |
| 2017 | 2031 | if (action === "merge") void perform("merge", selectedMergeMethod); |
| 2018 | 2032 | if (action === "enable-auto-merge") |
| 2019 | 2033 | void perform("enable-auto-merge", selectedMergeMethod); |
| ... | ... | @@ -2021,7 +2035,7 @@ export function PullRequestDetailPanel({ |
| 2021 | 2035 | }} |
| 2022 | 2036 | > |
| 2023 | 2037 | {confirmAction === "merge" |
| 2024 | | ? "Merge" |
| 2038 | ? selectedMergeMethodLabel |
| 2025 | 2039 | : confirmAction === "enable-auto-merge" |
| 2026 | 2040 | ? "Enable auto-merge" |
| 2027 | 2041 | : "Close"} |