Skip to content

Commit

Permalink
Display status check information on description page (#713)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rachel Macfarlane committed Dec 3, 2018
1 parent d365892 commit 1309f2d
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 6 deletions.
2 changes: 2 additions & 0 deletions preview-src/cache.ts
Expand Up @@ -6,6 +6,7 @@
import { vscode } from './message';
import { PullRequestStateEnum } from '../src/github/interface';
import { TimelineEvent } from '../src/common/timelineEvent';
import { ReposGetCombinedStatusForRefResponse } from '@octokit/rest';

export interface PullRequest {
number: number;
Expand All @@ -25,6 +26,7 @@ export interface PullRequest {
canEdit: boolean;
pendingCommentText?: string;
pendingCommentDrafts?: { [key: string]: string; };
status: ReposGetCombinedStatusForRefResponse;
}

export function getState(): PullRequest {
Expand Down
22 changes: 22 additions & 0 deletions preview-src/index.css
Expand Up @@ -118,6 +118,28 @@ body .comment-container .review-comment-header a {
height: 14px;
}

.status-check {
display: flex;
align-items: center;
margin-top: 5px;
margin-left: 15px;
}

#status-checks {
margin-top: 5px;
}

#status-checks summary {
display: flex;
align-items: center;
}

#status-checks svg {
fill: var(--vscode-foreground);
margin-right: 6px;
width: 12px;
}

body .comment-container .review-comment-header > span,
body .comment-container .review-comment-header > a,
body .commit .commit-message > a {
Expand Down
3 changes: 2 additions & 1 deletion preview-src/index.ts
Expand Up @@ -7,7 +7,7 @@ import * as debounce from 'debounce';
import { dateFromNow } from '../src/common/utils';
import { EventType } from '../src/common/timelineEvent';
import { PullRequestStateEnum } from '../src/github/interface';
import { renderTimelineEvent, getStatus, renderComment, renderReview, ActionsBar } from './pullRequestOverviewRenderer';
import { renderTimelineEvent, getStatus, renderComment, renderReview, ActionsBar, renderStatusChecks } from './pullRequestOverviewRenderer';
import md from './mdRenderer';
const emoji = require('node-emoji');
import { getMessageHandler } from './message';
Expand Down Expand Up @@ -60,6 +60,7 @@ function renderPullRequest(pr: PullRequest): void {
renderTimelineEvents(pr);
setTitleHTML(pr);
setTextArea();
renderStatusChecks(pr.status);
updateCheckoutButton(pr.isCurrentlyCheckedOut);
updatePullRequestState(pr.state);

Expand Down
83 changes: 81 additions & 2 deletions preview-src/pullRequestOverviewRenderer.ts
Expand Up @@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/


import { dateFromNow } from '../src/common/utils';
import { TimelineEvent, CommitEvent, ReviewEvent, CommentEvent, EventType, isCommentEvent } from '../src/common/timelineEvent';
import { PullRequestStateEnum } from '../src/github/interface';
Expand All @@ -15,6 +14,8 @@ import { Comment } from '../src/common/comment';
const commitIconSvg = require('../resources/icons/commit_icon.svg');
const editIcon = require('../resources/icons/edit.svg');
const deleteIcon = require('../resources/icons/delete.svg');
const checkIcon = require('../resources/icons/check.svg');
const dotIcon = require('../resources/icons/dot.svg');

const emoji = require('node-emoji');

Expand Down Expand Up @@ -43,6 +44,84 @@ function groupBy<T>(arr: T[], fn: (el: T) => string): { [key: string]: T[] } {
}, Object.create(null));
}

function getSummaryLabel(statuses: any[]) {
const statusTypes = groupBy(statuses, (status: any) => status.state);
let statusPhrases = [];
for (let statusType of Object.keys(statusTypes)) {
const numOfType = statusTypes[statusType].length;
let statusAdjective = '';

switch (statusType) {
case 'success':
statusAdjective = 'successful';
break;
case 'failure':
statusAdjective = 'failed';
break;
default:
statusAdjective = 'pending';
}

const status = numOfType > 1
? `${numOfType} ${statusAdjective} checks`
: `${numOfType} ${statusAdjective} check`;

statusPhrases.push(status);
}

return statusPhrases.join(' and ');
}

function getStateIcon(state: string) {
if (state === 'success') {
return checkIcon;
} else if (state === 'failure') {
return deleteIcon;
} else {
return dotIcon;
}
}

export function renderStatusChecks(statusInfo: any) {
const statusContainer: HTMLDetailsElement = document.getElementById('status-checks') as HTMLDetailsElement;
statusContainer.innerHTML = '';

if (!statusInfo.statuses.length) {
statusContainer.classList.add('hidden');
return;
}

statusContainer.open = statusInfo.state !== 'success';

const statusSummary = document.createElement('summary');
const statusSummaryIcon = document.createElement('span');
const statusSummaryText = document.createElement('span');
statusSummaryIcon.innerHTML = getStateIcon(statusInfo.state);
statusSummary.appendChild(statusSummaryIcon);
statusSummaryText.textContent = getSummaryLabel(statusInfo.statuses);
statusSummary.appendChild(statusSummaryText);
statusContainer.appendChild(statusSummary);

statusInfo.statuses.forEach(status => {
const statusElement: HTMLDivElement = document.createElement('div');
statusElement.className = 'status-check';

const state: HTMLSpanElement = document.createElement('span');
state.innerHTML = getStateIcon(status.state);

statusElement.appendChild(state);

const statusIcon = renderUserIcon(status.url, status.avatar_url);
statusElement.appendChild(statusIcon);

const statusDescription = document.createElement('span');
statusDescription.textContent = `${status.context} - ${status.description}`;
statusElement.appendChild(statusDescription);

statusContainer.appendChild(statusElement);
});
}

function renderUserIcon(iconLink: string, iconSrc: string): HTMLElement {
const iconContainer: HTMLDivElement = document.createElement('div');
iconContainer.className = 'avatar-container';
Expand Down Expand Up @@ -296,7 +375,7 @@ class CommentNode {
comment: this._comment
}
});
}
};

this._commentBody.appendChild(replyButton);
}
Expand Down
1 change: 1 addition & 0 deletions resources/icons/check.svg
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/dot.svg
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 src/github/interface.ts
Expand Up @@ -140,6 +140,7 @@ export interface IPullRequestManager {
requestChanges(pullRequest: IPullRequestModel, message?: string): Promise<any>;
getPullRequestChangedFiles(pullRequest: IPullRequestModel): Promise<Github.PullRequestsGetFilesResponseItem[]>;
getPullRequestRepositoryDefaultBranch(pullRequest: IPullRequestModel): Promise<string>;
getStatusChecks(pullRequest: IPullRequestModel): Promise<Github.ReposGetCombinedStatusForRefResponse>;

/**
* Fullfill information for a pull request which we can't fetch with one single api call.
Expand Down
12 changes: 12 additions & 0 deletions src/github/pullRequestManager.ts
Expand Up @@ -339,6 +339,18 @@ export class PullRequestManager implements IPullRequestManager {
return this._githubRepositories.some(repo => this._repositoryPageInformation.get(repo.remote.url.toString()).hasMorePages !== false);
}

async getStatusChecks(pullRequest: IPullRequestModel): Promise<Github.ReposGetCombinedStatusForRefResponse> {
const { remote, octokit } = await (pullRequest as PullRequestModel).githubRepository.ensure();

const result = await octokit.repos.getCombinedStatusForRef({
owner: remote.owner,
repo: remote.repositoryName,
ref: pullRequest.head.sha
});

return result.data;
}

async getPullRequestComments(pullRequest: IPullRequestModel): Promise<Comment[]> {
Logger.debug(`Fetch comments of PR #${pullRequest.prNumber} - enter`, PullRequestManager.ID);
const { remote, octokit } = await (pullRequest as PullRequestModel).githubRepository.ensure();
Expand Down
11 changes: 8 additions & 3 deletions src/github/pullRequestOverview.ts
Expand Up @@ -142,10 +142,11 @@ export class PullRequestOverviewPanel {
Promise.all(
[
this._pullRequestManager.getTimelineEvents(pullRequestModel),
this._pullRequestManager.getPullRequestRepositoryDefaultBranch(pullRequestModel)
this._pullRequestManager.getPullRequestRepositoryDefaultBranch(pullRequestModel),
this._pullRequestManager.getStatusChecks(pullRequestModel)
]
).then(result => {
const [timelineEvents, defaultBranch] = result;
const [timelineEvents, defaultBranch, status] = result;
this._postMessage({
command: 'pr.initialize',
pullrequest: {
Expand All @@ -163,9 +164,12 @@ export class PullRequestOverviewPanel {
head: pullRequestModel.head && pullRequestModel.head.label || 'UNKNOWN',
commitsCount: pullRequestModel.commitCount,
repositoryDefaultBranch: defaultBranch,
canEdit: canEdit
canEdit: canEdit,
status: status
}
});
}).catch(e => {
vscode.window.showErrorMessage(formatError(e));
});
}
}
Expand Down Expand Up @@ -461,6 +465,7 @@ export class PullRequestOverviewPanel {
<script nonce="${nonce}" src="${scriptUri}"></script>
<div id="title" class="title"></div>
<div id="timeline-events" class="discussion" aria-live="polite"></div>
<details id="status-checks"></details>
<div id="comment-form" class="comment-form"></div>
</body>
</html>`;
Expand Down

0 comments on commit 1309f2d

Please sign in to comment.