Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,11 @@
"title": "%command.pr.createPrMenuRebase.title%",
"category": "%command.pull.request.category%"
},
{
"command": "issue.openDescription",
"title": "%command.issue.openDescription.title%",
"category": "%command.issues.category%"
},
{
"command": "issue.createIssueFromSelection",
"title": "%command.issue.createIssueFromSelection.title%",
Expand Down Expand Up @@ -2070,6 +2075,10 @@
"command": "pr.acceptMerge",
"when": "isMergeResultEditor && mergeEditorBaseUri =~ /^(githubpr|gitpr):/"
},
{
"command": "issue.openDescription",
"when": "false"
},
{
"command": "issue.copyGithubPermalink",
"when": "github:hasGitHubRemotes"
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"command.pr.closeRelatedEditors.title": "Close All Pull Request Editors",
"command.pr.toggleEditorCommentingOn.title": "Toggle Editor Commenting On",
"command.pr.toggleEditorCommentingOff.title": "Toggle Editor Commenting Off",
"command.issue.openDescription.title": "View Issue Description",
"command.issue.copyGithubDevLink.title": "Copy github.dev Link",
"command.issue.copyGithubPermalink.title": "Copy GitHub Permalink",
"command.issue.copyGithubHeadLink.title": "Copy GitHub Head Link",
Expand Down
1 change: 1 addition & 0 deletions resources/icons/issue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/icons/issue_closed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
119 changes: 68 additions & 51 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,37 @@ function ensurePR<TIssue extends Issue, TIssueModel extends IssueModel<TIssue>>(

export async function openDescription(
telemetry: ITelemetry,
pullRequestModel: IssueModel,
issueModel: IssueModel,
descriptionNode: DescriptionNode | undefined,
folderManager: FolderRepositoryManager,
revealNode: boolean,
preserveFocus: boolean = true,
notificationProvider?: NotificationProvider
) {
const pullRequest = ensurePR(folderManager, pullRequestModel);
const issue = ensurePR(folderManager, issueModel);
if (revealNode) {
descriptionNode?.reveal(descriptionNode, { select: true, focus: true });
}
// Create and show a new webview
if (pullRequest instanceof PullRequestModel) {
await PullRequestOverviewPanel.createOrShow(telemetry, folderManager.context.extensionUri, folderManager, pullRequest, undefined, preserveFocus);
if (issue instanceof PullRequestModel) {
await PullRequestOverviewPanel.createOrShow(telemetry, folderManager.context.extensionUri, folderManager, issue, undefined, preserveFocus);
/* __GDPR__
"pr.openDescription" : {}
*/
telemetry.sendTelemetryEvent('pr.openDescription');
} else {
await IssueOverviewPanel.createOrShow(telemetry, folderManager.context.extensionUri, folderManager, pullRequest);
await IssueOverviewPanel.createOrShow(telemetry, folderManager.context.extensionUri, folderManager, issue);
/* __GDPR__
"issue.openDescription" : {}
*/
telemetry.sendTelemetryEvent('issue.openDescription');
}

if (notificationProvider?.hasNotification(pullRequest)) {
notificationProvider.markPrNotificationsAsRead(pullRequest);
if (notificationProvider?.hasNotification(issue)) {
notificationProvider.markPrNotificationsAsRead(issue);
}

/* __GDPR__
"pr.openDescription" : {}
*/
telemetry.sendTelemetryEvent('pr.openDescription');

}

async function chooseItem<T>(
Expand All @@ -115,7 +120,7 @@ async function chooseItem<T>(
return (await vscode.window.showQuickPick(items, options))?.itemValue;
}

export async function openPullRequestOnGitHub(e: PRNode | DescriptionNode | PullRequestModel | NotificationTreeItem, telemetry: ITelemetry) {
export async function openPullRequestOnGitHub(e: PRNode | DescriptionNode | IssueModel | NotificationTreeItem, telemetry: ITelemetry) {
if (e instanceof PRNode || e instanceof DescriptionNode) {
vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(e.pullRequestModel.html_url));
} else if (isNotificationTreeItem(e)) {
Expand Down Expand Up @@ -805,50 +810,61 @@ export function registerCommands(
}),
);

context.subscriptions.push(
vscode.commands.registerCommand(
'pr.openDescription',
async (argument: DescriptionNode | IssueModel | undefined) => {
let pullRequestModel: IssueModel | undefined;
if (!argument) {
const activePullRequests: PullRequestModel[] = reposManager.folderManagers
.map(manager => manager.activePullRequest!)
.filter(activePR => !!activePR);
if (activePullRequests.length >= 1) {
pullRequestModel = await chooseItem<PullRequestModel>(
activePullRequests,
itemValue => itemValue.title,
);
}
} else {
pullRequestModel = argument instanceof DescriptionNode ? argument.pullRequestModel : argument;
}
async function openDescriptionCommand(argument: DescriptionNode | IssueModel | undefined) {
let issueModel: IssueModel | undefined;
if (!argument) {
const activePullRequests: PullRequestModel[] = reposManager.folderManagers
.map(manager => manager.activePullRequest!)
.filter(activePR => !!activePR);
if (activePullRequests.length >= 1) {
issueModel = await chooseItem<PullRequestModel>(
activePullRequests,
itemValue => itemValue.title,
);
}
} else {
issueModel = argument instanceof DescriptionNode ? argument.pullRequestModel : argument;
}

if (!pullRequestModel) {
Logger.appendLine('No pull request found.', logId);
return;
}
if (!issueModel) {
Logger.appendLine('No pull request found.', logId);
return;
}

const folderManager = reposManager.getManagerForIssueModel(pullRequestModel);
if (!folderManager) {
return;
}
const folderManager = reposManager.getManagerForIssueModel(issueModel);
if (!folderManager) {
return;
}

let descriptionNode: DescriptionNode | undefined;
if (argument instanceof DescriptionNode) {
descriptionNode = argument;
} else {
const reviewManager = ReviewManager.getReviewManagerForFolderManager(reviewsManager.reviewManagers, folderManager);
if (!reviewManager) {
return;
}
let descriptionNode: DescriptionNode | undefined;
if (argument instanceof DescriptionNode) {
descriptionNode = argument;
} else {
const reviewManager = ReviewManager.getReviewManagerForFolderManager(reviewsManager.reviewManagers, folderManager);
if (!reviewManager) {
return;
}

descriptionNode = reviewManager.changesInPrDataProvider.getDescriptionNode(folderManager);
}
descriptionNode = reviewManager.changesInPrDataProvider.getDescriptionNode(folderManager);
}

await openDescription(telemetry, pullRequestModel, descriptionNode, folderManager, !(argument instanceof DescriptionNode), !(argument instanceof RepositoryChangesNode), tree.notificationProvider);
},
),
const revealDescription = !(argument instanceof DescriptionNode) && (!(argument instanceof IssueModel) || (argument instanceof PullRequestModel));

await openDescription(telemetry, issueModel, descriptionNode, folderManager, revealDescription, !(argument instanceof RepositoryChangesNode), tree.notificationProvider);
}

context.subscriptions.push(
vscode.commands.registerCommand(
'pr.openDescription',
openDescriptionCommand
)
);

context.subscriptions.push(
vscode.commands.registerCommand(
'issue.openDescription',
openDescriptionCommand
)
);

context.subscriptions.push(
Expand Down Expand Up @@ -1460,6 +1476,7 @@ ${contents}
vscode.env.openExternal(getPullsUrl(githubRepo));
}
}));

context.subscriptions.push(
vscode.commands.registerCommand('issues.openIssuesWebsite', async () => {
const githubRepo = await chooseRepoToOpen();
Expand Down
2 changes: 1 addition & 1 deletion src/common/timelineEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export interface CommentEvent {
htmlUrl: string;
body: string;
bodyHTML?: string;
user: IAccount;
user?: IAccount;
event: EventType.Commented;
canEdit?: boolean;
canDelete?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions src/github/folderRepositoryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2087,9 +2087,9 @@ export class FolderRepositoryManager extends Disposable {
}

async getPullRequestRepositoryAccessAndMergeMethods(
pullRequest: PullRequestModel,
issue: IssueModel,
): Promise<RepoAccessAndMergeMethods> {
const mergeOptions = await pullRequest.githubRepository.getRepoAccessAndMergeMethods();
const mergeOptions = await issue.githubRepository.getRepoAccessAndMergeMethods();
return mergeOptions;
}

Expand Down
5 changes: 3 additions & 2 deletions src/github/githubRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
GetBranchResponse,
GetChecksResponse,
isCheckRun,
IssueResponse,
IssuesSearchResponse,
ListBranchesResponse,
MaxIssueResponse,
Expand Down Expand Up @@ -1003,7 +1004,7 @@ export class GitHubRepository extends Disposable {
Logger.debug(`Fetch issue ${id} - enter`, this.id);
const { query, remote, schema } = await this.ensure();

const { data } = await query<PullRequestResponse>({
const { data } = await query<IssueResponse>({
query: withComments ? schema.IssueWithComments : schema.Issue,
variables: {
owner: remote.owner,
Expand All @@ -1018,7 +1019,7 @@ export class GitHubRepository extends Disposable {
}
Logger.debug(`Fetch issue ${id} - done`, this.id);

return new IssueModel(this, remote, parseGraphQLIssue(data.repository.pullRequest, this));
return new IssueModel(this, remote, parseGraphQLIssue(data.repository.issue, this));
} catch (e) {
Logger.error(`Unable to fetch issue: ${e}`, this.id);
return;
Expand Down
79 changes: 45 additions & 34 deletions src/github/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,9 +450,9 @@ export interface DeleteReactionResponse {
};
}

export interface UpdatePullRequestResponse {
updatePullRequest: {
pullRequest: {
export interface UpdateIssueResponse {
updateIssue: {
issue: {
body: string;
bodyHTML: string;
title: string;
Expand Down Expand Up @@ -522,12 +522,12 @@ export interface SuggestedReviewerResponse {
export type MergeMethod = 'MERGE' | 'REBASE' | 'SQUASH';
export type MergeQueueState = 'AWAITING_CHECKS' | 'LOCKED' | 'MERGEABLE' | 'QUEUED' | 'UNMERGEABLE';

export interface PullRequest {
export interface Issue {
id: string;
databaseId: number;
number: number;
url: string;
state: 'OPEN' | 'CLOSED' | 'MERGED';
state: 'OPEN' | 'CLOSED' | 'MERGED'; // TODO: don't allow merged in an issue
body: string;
bodyHTML: string;
title: string;
Expand All @@ -536,48 +536,19 @@ export interface PullRequest {
nodes: Account[];
};
author: Account;
commits: {
nodes: {
commit: {
message: string;
};
}[];
};
comments: {
nodes?: AbbreviatedIssueComment[];
totalCount: number;
};
createdAt: string;
updatedAt: string;
headRef?: Ref;
headRefName: string;
headRefOid: string;
headRepository?: RefRepository;
baseRef?: Ref;
baseRefName: string;
baseRefOid: string;
baseRepository: BaseRefRepository;
labels: {
nodes: {
name: string;
color: string;
}[];
};
merged: boolean;
mergeable: 'MERGEABLE' | 'CONFLICTING' | 'UNKNOWN';
mergeQueueEntry?: MergeQueueEntry | null;
mergeStateStatus: 'BEHIND' | 'BLOCKED' | 'CLEAN' | 'DIRTY' | 'HAS_HOOKS' | 'UNKNOWN' | 'UNSTABLE';
reviewThreads: {
totalCount: number;
}
autoMergeRequest?: {
mergeMethod: MergeMethod;
};
viewerCanEnableAutoMerge: boolean;
viewerCanDisableAutoMerge: boolean;
viewerCanUpdate: boolean;
isDraft?: boolean;
suggestedReviewers: SuggestedReviewerResponse[];
projectItems?: {
nodes: {
project: {
Expand Down Expand Up @@ -606,6 +577,39 @@ export interface PullRequest {
}
}


export interface PullRequest extends Issue {
commits: {
nodes: {
commit: {
message: string;
};
}[];
};
headRef?: Ref;
headRefName: string;
headRefOid: string;
headRepository?: RefRepository;
baseRef?: Ref;
baseRefName: string;
baseRefOid: string;
baseRepository: BaseRefRepository;
merged: boolean;
mergeable: 'MERGEABLE' | 'CONFLICTING' | 'UNKNOWN';
mergeQueueEntry?: MergeQueueEntry | null;
mergeStateStatus: 'BEHIND' | 'BLOCKED' | 'CLEAN' | 'DIRTY' | 'HAS_HOOKS' | 'UNKNOWN' | 'UNSTABLE';
reviewThreads: {
totalCount: number;
}
autoMergeRequest?: {
mergeMethod: MergeMethod;
};
viewerCanEnableAutoMerge: boolean;
viewerCanDisableAutoMerge: boolean;
isDraft?: boolean;
suggestedReviewers: SuggestedReviewerResponse[];
}

export enum DefaultCommitTitle {
prTitle = 'PR_TITLE',
commitOrPrTitle = 'COMMIT_OR_PR_TITLE',
Expand All @@ -626,6 +630,13 @@ export interface PullRequestResponse {
rateLimit: RateLimit;
}

export interface IssueResponse {
repository: {
issue: PullRequest;
} | null;
rateLimit: RateLimit;
}

export interface PullRequestMergabilityResponse {
repository: {
pullRequest: {
Expand Down
2 changes: 1 addition & 1 deletion src/github/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ export interface IPullRequestsPagingOptions {
fetchOnePagePerRepo?: boolean;
}

export interface IPullRequestEditData {
export interface IIssueEditData {
body?: string;
title?: string;
}
Expand Down
Loading