Skip to content

Commit

Permalink
WIP Document TS
Browse files Browse the repository at this point in the history
  • Loading branch information
Frédéric Collonval committed Mar 3, 2021
1 parent 522f0d1 commit 79e06da
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 126 deletions.
1 change: 1 addition & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@
- [ ] Organize PR by project
- [ ] TBC Switch to current folder remote
- [ ] Use jlab codeeditor settings for merge view codemirror
- [ ] Add Myers algorithm to nbdime
33 changes: 31 additions & 2 deletions src/components/PullRequestPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { PullRequestBrowser } from './browser/PullRequestBrowser';
import { PullRequestToolbar } from './PullRequestToolbar';

/**
* React wrapper to mount and unmount the React child component
* React wrapper to mount and umount the React child component
* when the widget is shown/hidden.
*
* In this case this is particularly interesting to trigger the
Expand Down Expand Up @@ -50,21 +50,45 @@ export class PullRequestPanelWrapper extends ReactWidget {
private _docRegistry: DocumentRegistry;
}

/**
* PullRequestPanel properties
*/
export interface IPullRequestPanelProps {
/**
* Jupyter Front End Commands Registry
*/
commands: CommandRegistry;
/**
* Document registry
*/
docRegistry: DocumentRegistry;
}

/**
* Available pull request filter
*/
type Filter = 'created' | 'assigned';

/**
* Pull request filter
*/
interface IFilter {
/**
* Filter name
*/
name: string;
/**
* Filter type
*/
filter: Filter;
}

/**
* Get a group of pull requests for each filters
*
* @param filters Filter types
* @returns The group of pull requests
*/
async function fetchPullRequests(
filters: IFilter[]
): Promise<IPullRequestGroup[]> {
Expand Down Expand Up @@ -96,7 +120,12 @@ async function fetchPullRequests(
);
}

function PullRequestPanel(props: IPullRequestPanelProps): JSX.Element {
/**
* PullRequestPanel component
*
* @param props PullRequestPanel properties
*/
export function PullRequestPanel(props: IPullRequestPanelProps): JSX.Element {
const [pullRequests, setPullRequests] = useState<IPullRequestGroup[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(true);
const refreshPullRequests = (): void => {
Expand Down
8 changes: 8 additions & 0 deletions src/components/PullRequestToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@ import React from 'react';
import { refreshIcon } from '@jupyterlab/ui-components';
import { ActionButton } from '@jupyterlab/git/lib/components/ActionButton';

/**
* PullRequestToolbar properties
*/
export interface IPullRequestToolbarProps {
/**
* Refresh button callback
*/
onRefresh: () => void;
}

/**
* PullRequestToolbar component
*
* @param props Component properties
*/
export function PullRequestToolbar(
props: IPullRequestToolbarProps
): JSX.Element {
Expand Down
193 changes: 90 additions & 103 deletions src/components/diff/notebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ import { Panel, Widget } from '@lumino/widgets';
import jsonMap from 'json-source-map';
import { IDiffEntry } from 'nbdime/lib/diff/diffentries';
import { CellDiffModel, NotebookDiffModel } from 'nbdime/lib/diff/model';
import { CELLDIFF_CLASS } from 'nbdime/lib/diff/widget';
import {
CHUNK_PANEL_CLASS,
UNCHANGED_DIFF_CLASS
} from 'nbdime/lib/diff/widget/common';
import {
IDiffOptions,
INotebookMapping,
Expand All @@ -38,38 +33,33 @@ const NBDIME_CLASS = 'nbdime-Widget';
*/
const ROOT_CLASS = 'nbdime-root';

/**
* DOM class for whether or not to hide unchanged cells
*/
const HIDE_UNCHANGED_CLASS = 'jp-mod-hideUnchanged';

export class NotebookDiff extends Panel {
constructor(props: IDiffOptions) {
super();
this.addClass(NBDIME_CLASS);
this.scroller = new Panel();
this.scroller.addClass(ROOT_CLASS);
this.scroller.node.tabIndex = -1;

const header = Private.diffHeader(
props.diff.base.label,
props.diff.head.label
);
this.addWidget(header);
this.scroller.addWidget(header);

this.scroller = new Panel();
this.scroller.addClass(ROOT_CLASS);
this.scroller.node.tabIndex = -1;
this.addWidget(this.scroller);

const hideUnchangedChk = header.node.getElementsByClassName(
'nbdime-hide-unchanged'
)[0] as HTMLInputElement;
hideUnchangedChk.checked =
props.hideUnchanged === undefined ? true : props.hideUnchanged;
hideUnchangedChk.onchange = (): void => {
Private.toggleShowUnchanged(this.scroller, !hideUnchangedChk.checked);
};
if (props.hideUnchanged) {
Private.toggleShowUnchanged(this.scroller, false);
}
// const hideUnchangedChk = header.node.getElementsByClassName(
// 'nbdime-hide-unchanged'
// )[0] as HTMLInputElement;
// hideUnchangedChk.checked =
// props.hideUnchanged === undefined ? true : props.hideUnchanged;
// hideUnchangedChk.onchange = (): void => {
// Private.toggleShowUnchanged(this.scroller, !hideUnchangedChk.checked);
// };
// if (props.hideUnchanged) {
// Private.toggleShowUnchanged(this.scroller, false);
// }

this.computeDiff(props.diff.base.content, props.diff.head.content)
.then(data => {
Expand Down Expand Up @@ -268,7 +258,7 @@ export class NotebookDiff extends Panel {
const work = nbdWidget.init();
work
.then(() => {
Private.markUnchangedRanges(this.scroller.node);
// Private.markUnchangedRanges(this.scroller.node);
})
.catch(error => {
console.error('Failed to mark unchanged ranges', error);
Expand Down Expand Up @@ -319,17 +309,14 @@ namespace Private {
* Create a header widget for the diff view.
*/
export function diffHeader(baseLabel: string, remoteLabel: string): Widget {
const node = generateNode('div', { class: 'nbdime-Diff jp-git-diff-root' });
const node = generateNode('div', { class: 'jp-git-diff-banner' });

node.innerHTML = `
<div class="nbdime-header-buttonrow">
<label><input class="nbdime-hide-unchanged" type="checkbox">Hide unchanged cells</label>
<button class="nbdime-export" style="display: none">Export diff</button>
</div>
<div class=jp-git-diff-banner>
<span>${baseLabel}</span>
<span>${remoteLabel}</span>
</div>`;
// <div class="nbdime-header-buttonrow">
// <label><input class="nbdime-hide-unchanged" type="checkbox">Hide unchanged cells</label>
// <button class="nbdime-export" style="display: none">Export diff</button>
// </div>
node.innerHTML = `<span>${baseLabel}</span>
<span>${remoteLabel}</span>`;

return new Widget({ node });
}
Expand All @@ -339,80 +326,80 @@ namespace Private {
*
* This simply marks with a class, real work is done by CSS.
*/
export function toggleShowUnchanged(root: Widget, show?: boolean): void {
const hiding = root.hasClass(HIDE_UNCHANGED_CLASS);
if (show === undefined) {
show = hiding;
} else if (hiding !== show) {
// Nothing to do
return;
}
if (show) {
root.removeClass(HIDE_UNCHANGED_CLASS);
} else {
markUnchangedRanges(root.node);
root.addClass(HIDE_UNCHANGED_CLASS);
}
root.update();
}
// export function toggleShowUnchanged(root: Widget, show?: boolean): void {
// const hiding = root.hasClass(HIDE_UNCHANGED_CLASS);
// if (show === undefined) {
// show = hiding;
// } else if (hiding !== show) {
// // Nothing to do
// return;
// }
// if (show) {
// root.removeClass(HIDE_UNCHANGED_CLASS);
// } else {
// markUnchangedRanges(root.node);
// root.addClass(HIDE_UNCHANGED_CLASS);
// }
// root.update();
// }

/**
* Gets the chunk element of an added/removed cell, or the cell element for others
* @param cellElement
*/
function getChunkElement(cellElement: Element): Element {
if (
!cellElement.parentElement ||
!cellElement.parentElement.parentElement
) {
return cellElement;
}
const chunkCandidate = cellElement.parentElement.parentElement;
if (chunkCandidate.classList.contains(CHUNK_PANEL_CLASS)) {
return chunkCandidate;
}
return cellElement;
}
// function getChunkElement(cellElement: Element): Element {
// if (
// !cellElement.parentElement ||
// !cellElement.parentElement.parentElement
// ) {
// return cellElement;
// }
// const chunkCandidate = cellElement.parentElement.parentElement;
// if (chunkCandidate.classList.contains(CHUNK_PANEL_CLASS)) {
// return chunkCandidate;
// }
// return cellElement;
// }

/**
* Marks certain cells with
*/
export function markUnchangedRanges(root: HTMLElement): void {
const children = root.querySelectorAll(`.${CELLDIFF_CLASS}`);
let rangeStart = -1;
for (let i = 0; i < children.length; ++i) {
const child = children[i];
if (!child.classList.contains(UNCHANGED_DIFF_CLASS)) {
// Visible
if (rangeStart !== -1) {
// Previous was hidden
const N = i - rangeStart;
getChunkElement(child).setAttribute(
'data-nbdime-NCellsHiddenBefore',
N.toString()
);
rangeStart = -1;
}
} else if (rangeStart === -1) {
rangeStart = i;
}
}
if (rangeStart !== -1) {
// Last element was part of a hidden range, need to mark
// the last cell that will be visible.
const N = children.length - rangeStart;
if (rangeStart === 0) {
// All elements were hidden, nothing to mark
// Add info on root instead
const tag = root.querySelector('.jp-Notebook-diff') || root;
tag.setAttribute('data-nbdime-AllCellsHidden', N.toString());
return;
}
const lastVisible = children[rangeStart - 1];
getChunkElement(lastVisible).setAttribute(
'data-nbdime-NCellsHiddenAfter',
N.toString()
);
}
}
// export function markUnchangedRanges(root: HTMLElement): void {
// const children = root.querySelectorAll(`.${CELLDIFF_CLASS}`);
// let rangeStart = -1;
// for (let i = 0; i < children.length; ++i) {
// const child = children[i];
// if (!child.classList.contains(UNCHANGED_DIFF_CLASS)) {
// // Visible
// if (rangeStart !== -1) {
// // Previous was hidden
// const N = i - rangeStart;
// getChunkElement(child).setAttribute(
// 'data-nbdime-NCellsHiddenBefore',
// N.toString()
// );
// rangeStart = -1;
// }
// } else if (rangeStart === -1) {
// rangeStart = i;
// }
// }
// if (rangeStart !== -1) {
// // Last element was part of a hidden range, need to mark
// // the last cell that will be visible.
// const N = children.length - rangeStart;
// if (rangeStart === 0) {
// // All elements were hidden, nothing to mark
// // Add info on root instead
// const tag = root.querySelector('.jp-Notebook-diff') || root;
// tag.setAttribute('data-nbdime-AllCellsHidden', N.toString());
// return;
// }
// const lastVisible = children[rangeStart - 1];
// getChunkElement(lastVisible).setAttribute(
// 'data-nbdime-NCellsHiddenAfter',
// N.toString()
// );
// }
// }
}
6 changes: 6 additions & 0 deletions src/components/tab/PullRequestDescriptionTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { IComment, IPullRequest, IThread } from '../../tokens';
import { generateNode, requestAPI } from '../../utils';
import { CommentThread } from '../diff/CommentThread';

/**
* PullRequestDescriptionTab properties
*/
export interface IPullRequestDescriptionTabProps {
/**
* Pull Request data
Expand All @@ -17,6 +20,9 @@ export interface IPullRequestDescriptionTabProps {
renderMime: IRenderMimeRegistry;
}

/**
* PullRequestDescriptionTab component
*/
export class PullRequestDescriptionTab extends MainAreaWidget<Panel> {
constructor(props: IPullRequestDescriptionTabProps) {
const content = new Panel();
Expand Down
8 changes: 6 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const pullRequestPlugin: JupyterFrontEndPlugin<void> = {
autoStart: true
};

/**
* Search for a widget in the shell main area
*
* @param shell JupyterLab shell
* @param id Widget id
*/
function findWidget(
shell: JupyterFrontEnd.IShell,
id: string
Expand All @@ -43,7 +49,6 @@ function findWidget(
return mainAreaItem;
}

// Master extension activate
function activate(
app: JupyterFrontEnd,
restorer: ILayoutRestorer,
Expand Down Expand Up @@ -118,7 +123,6 @@ function activate(

// Create the Pull Request widget sidebar
const prPanel = new PullRequestPanelWrapper(commands, app.docRegistry);

prPanel.id = 'pullRequests';
prPanel.title.icon = pullRequestsIcon;
prPanel.title.caption = 'Pull Requests';
Expand Down
Loading

0 comments on commit 79e06da

Please sign in to comment.