Skip to content

Commit bfd57e5

Browse files
Copilotalexr00
andcommitted
Implement PR picker for checkout command
- Added QuickPick to show all open PRs when checking out - Allow filtering by number, title, or author in the picker - Support typing custom PR number or URL - Renamed command to "Checkout Pull Request..." - Import PRType for fetching all PRs Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent 9d0857c commit bfd57e5

File tree

2 files changed

+63
-19
lines changed

2 files changed

+63
-19
lines changed

package.nls.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@
210210
"command.pr.focusDescriptionInput.title": "Focus Pull Request Description Review Input",
211211
"command.pr.showDiffSinceLastReview.title": "Show Changes Since Last Review",
212212
"command.pr.showDiffAll.title": "Show All Changes",
213-
"command.pr.checkoutByNumber.title": "Checkout Pull Request by Number",
213+
"command.pr.checkoutByNumber.title": "Checkout Pull Request...",
214214
"command.review.openFile.title": "Open File",
215215
"command.review.openLocalFile.title": "Open File",
216216
"command.review.approve.title": "Approve",

src/commands.ts

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { ChatSessionWithPR, CrossChatSessionWithPR } from './github/copilotApi';
2323
import { CopilotRemoteAgentManager, SessionIdForPr } from './github/copilotRemoteAgent';
2424
import { FolderRepositoryManager } from './github/folderRepositoryManager';
2525
import { GitHubRepository } from './github/githubRepository';
26-
import { Issue } from './github/interface';
26+
import { Issue, PRType } from './github/interface';
2727
import { IssueModel } from './github/issueModel';
2828
import { IssueOverviewPanel } from './github/issueOverview';
2929
import { GHPRComment, GHPRCommentThread, TemporaryComment } from './github/prComment';
@@ -1604,26 +1604,70 @@ ${contents}
16041604
if (!githubRepo) {
16051605
return;
16061606
}
1607-
const prNumber = await vscode.window.showInputBox({
1608-
ignoreFocusOut: true, prompt: vscode.l10n.t('Enter the pull request number or URL'),
1609-
validateInput: (input: string) => {
1610-
const result = validateAndParseInput(input, githubRepo.repo.remote.owner, githubRepo.repo.remote.repositoryName);
1611-
return result.isValid ? undefined : result.errorMessage;
1607+
1608+
// Create QuickPick to show all PRs
1609+
const quickPick = vscode.window.createQuickPick<vscode.QuickPickItem & { pr?: PullRequestModel }>();
1610+
quickPick.placeholder = vscode.l10n.t('Select a pull request or enter a pull request number/URL');
1611+
quickPick.matchOnDescription = true;
1612+
quickPick.matchOnDetail = true;
1613+
quickPick.show();
1614+
quickPick.busy = true;
1615+
1616+
// Fetch all open PRs
1617+
try {
1618+
const prs = await githubRepo.manager.getPullRequests(PRType.All, { fetchNextPage: false });
1619+
const prItems: (vscode.QuickPickItem & { pr: PullRequestModel })[] = prs.items.map(pr => ({
1620+
label: `#${pr.number}`,
1621+
description: pr.title,
1622+
detail: `by @${pr.author.login}`,
1623+
pr
1624+
}));
1625+
1626+
quickPick.items = prItems;
1627+
quickPick.busy = false;
1628+
1629+
// Handle selection
1630+
const selected = await new Promise<(vscode.QuickPickItem & { pr?: PullRequestModel }) | string | undefined>((resolve) => {
1631+
quickPick.onDidAccept(() => {
1632+
if (quickPick.selectedItems.length > 0) {
1633+
resolve(quickPick.selectedItems[0]);
1634+
} else if (quickPick.value) {
1635+
// User typed something but didn't select from list
1636+
resolve(quickPick.value);
1637+
}
1638+
});
1639+
quickPick.onDidHide(() => resolve(undefined));
1640+
});
1641+
1642+
quickPick.hide();
1643+
quickPick.dispose();
1644+
1645+
if (!selected) {
1646+
return;
16121647
}
1613-
});
1614-
if ((prNumber === undefined) || prNumber === '#') {
1615-
return;
1616-
}
16171648

1618-
// Extract PR number from input (either direct number or URL)
1619-
const parseResult = validateAndParseInput(prNumber, githubRepo.repo.remote.owner, githubRepo.repo.remote.repositoryName);
1620-
if (!parseResult.isValid) {
1621-
return vscode.window.showErrorMessage(parseResult.errorMessage || vscode.l10n.t('Invalid pull request number or URL'));
1622-
}
1649+
let prModel: PullRequestModel | undefined;
16231650

1624-
const prModel = await githubRepo.manager.fetchById(githubRepo.repo, parseResult.prNumber);
1625-
if (prModel) {
1626-
return ReviewManager.getReviewManagerForFolderManager(reviewsManager.reviewManagers, githubRepo.manager)?.switch(prModel);
1651+
// Check if user selected from the list or typed a custom value
1652+
if (typeof selected === 'string') {
1653+
// User typed a PR number or URL
1654+
const parseResult = validateAndParseInput(selected, githubRepo.repo.remote.owner, githubRepo.repo.remote.repositoryName);
1655+
if (!parseResult.isValid) {
1656+
return vscode.window.showErrorMessage(parseResult.errorMessage || vscode.l10n.t('Invalid pull request number or URL'));
1657+
}
1658+
prModel = await githubRepo.manager.fetchById(githubRepo.repo, parseResult.prNumber);
1659+
} else if (selected.pr) {
1660+
// User selected from the list
1661+
prModel = selected.pr;
1662+
}
1663+
1664+
if (prModel) {
1665+
return ReviewManager.getReviewManagerForFolderManager(reviewsManager.reviewManagers, githubRepo.manager)?.switch(prModel);
1666+
}
1667+
} catch (e) {
1668+
quickPick.hide();
1669+
quickPick.dispose();
1670+
return vscode.window.showErrorMessage(vscode.l10n.t('Failed to fetch pull requests: {0}', formatError(e)));
16271671
}
16281672
}));
16291673

0 commit comments

Comments
 (0)