Skip to content

Commit

Permalink
Description tab as Panel widget
Browse files Browse the repository at this point in the history
  • Loading branch information
Frédéric Collonval committed Mar 1, 2021
1 parent a6ab476 commit db1cf57
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 54 deletions.
156 changes: 103 additions & 53 deletions src/components/tab/PullRequestDescriptionTab.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,53 @@
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
import { Widget } from '@lumino/widgets';
import { IPullRequest, IThread } from '../../tokens';
import { requestAPI } from '../../utils';
import { Panel, Widget } from '@lumino/widgets';
import { IComment, IPullRequest, IThread } from '../../tokens';
import { generateNode, requestAPI } from '../../utils';
import { CommentThread } from '../diff/CommentThread';

export interface IPullRequestDescriptionTabProps {
/**
* Pull Request data
*/
pullRequest: IPullRequest;
renderMimeRegistry: IRenderMimeRegistry;
/**
* Render mime type registry
*/
renderMime: IRenderMimeRegistry;
}

export class PullRequestDescriptionTab extends Widget {
export class PullRequestDescriptionTab extends Panel {
constructor(props: IPullRequestDescriptionTabProps) {
const markdownRenderer = props.renderMimeRegistry.createRenderer(
'text/markdown'
);
super();
this.pullRequestId = props.pullRequest.id;
this.renderMime = props.renderMime;
this.addClass('jp-PullRequestTab');

super({
node: PullRequestDescriptionTab.create(
props.pullRequest.title,
props.pullRequest.link,
markdownRenderer
)
});
const header = PullRequestDescriptionTab.createHeader(
props.pullRequest.title,
props.pullRequest.link
);
this.addWidget(
new Widget({
node: header
})
);

markdownRenderer.renderModel({
data: {
'text/markdown': props.pullRequest.body
},
trusted: false,
metadata: {},
setData: () => null
});
const markdownRenderer = props.renderMime.createRenderer('text/markdown');
this.addWidget(markdownRenderer);
markdownRenderer
.renderModel({
data: {
'text/markdown': props.pullRequest.body
},
trusted: false,
metadata: {},
setData: () => null
})
.catch(reason => {
console.error('Failed to render pull request description.', reason);
});

this.loadComments(props.pullRequest.id, props.renderMimeRegistry);
this.loadComments(props.pullRequest.id, props.renderMime);
}

protected loadComments(prId: string, renderMime: IRenderMimeRegistry): void {
Expand All @@ -41,43 +56,78 @@ export class PullRequestDescriptionTab extends Widget {
'GET'
)
.then(threads => {
this.threads = threads;

threads.forEach(thread => {
this.node.append(
new CommentThread({
renderMime,
thread,
handleRemove: () => null
}).node
);
const widget = new CommentThread({
renderMime,
thread,
handleRemove: (): void => null
});
this.addWidget(widget);
});

this.addNewThreadButton();
})
.catch(reason => {
console.error(reason);
this.addNewThreadButton();
});
}

private static create(
title: string,
link: string,
descriptionWidget: Widget
): HTMLDivElement {
const div1 = document.createElement('div');
div1.classList.add('jp-PullRequestTab');
const div2 = document.createElement('div');
div2.classList.add('jp-PullRequestDescriptionTab');
const h1 = document.createElement('h1');
h1.textContent = title;
const button = document.createElement('button');
button.classList.add('jp-Button-flat', 'jp-mod-styled', 'jp-mod-accept');
button.addEventListener('click', (): void => {
window.open(link, '_blank');
});
button.textContent = 'View Details';
div2.append(h1);
div2.append(descriptionWidget.node);
div2.append(button);
div1.append(div2);
private static createHeader(title: string, link: string): HTMLElement {
const div = generateNode('div', { class: 'jp-PullRequestDescriptionTab' });
div.appendChild(generateNode('h1', {}, title));
div.appendChild(
generateNode(
'button',
{ class: 'jp-Button-flat jp-mod-styled jp-mod-accept' },
'View Details',
{
click: (): void => {
window.open(link, '_blank');
}
}
)
);

return div;
}

private addNewThreadButton(): void {
const button = generateNode('button', {}, 'Start a new discussion', {
click: () => {
// Append an empty thread to start a new discussion
const hasNewThread =
this.threads[this.threads.length - 1]?.comments.length === 0;
if (!hasNewThread) {
const thread: IThread = {
comments: new Array<IComment>(),
pullRequestId: this.pullRequestId
};

this.threads.push(thread);

return div1;
const widget = new CommentThread({
thread,
renderMime: this.renderMime,
handleRemove: (): void => {
const threadIndex = this.threads.findIndex(
thread_ => thread.id === thread_.id
);
this.threads.splice(threadIndex, 1);
this.layout.removeWidget(widget);
widget.dispose();
}
});
this.insertWidget(this.widgets.length - 1, widget);
}
}
});
this.addWidget(new Widget({ node: button }));
}

protected pullRequestId: string;
protected renderMime: IRenderMimeRegistry;
protected threads: IThread[];
}
2 changes: 1 addition & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function activate(
mainAreaItem = new MainAreaWidget<PullRequestDescriptionTab>({
content: new PullRequestDescriptionTab({
pullRequest,
renderMimeRegistry: renderMime
renderMime
})
});
mainAreaItem.id = pullRequest.id;
Expand Down

0 comments on commit db1cf57

Please sign in to comment.