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