From 9fce54657cf3183e372bccf8153e6943eca5c238 Mon Sep 17 00:00:00 2001 From: Frederic COLLONVAL Date: Sun, 18 Apr 2021 12:11:38 +0200 Subject: [PATCH] Update to @jupyterlab/git and nbdime for JLab 3 --- package.json | 6 +-- setup.cfg | 6 +-- src/components/ActionButton.tsx | 43 ++++++++++++++++++++++ src/components/Toolbar.tsx | 2 +- src/components/browser/PullRequestItem.tsx | 2 +- src/components/diff/NotebookDiff.ts | 40 +++++++++++++++----- src/components/diff/plaintext.ts | 42 ++++++++++++--------- style/base.css | 21 ++++++++++- yarn.lock | 29 ++++++++------- 9 files changed, 141 insertions(+), 50 deletions(-) create mode 100644 src/components/ActionButton.tsx diff --git a/package.json b/package.json index ab9e287..a4665b3 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@jupyterlab/coreutils": "^5.0.3", "@jupyterlab/docregistry": "^3.0.6", "@jupyterlab/filebrowser": "^3.0.6", - "@jupyterlab/git": "0.30.0-beta.3 - 0.40.0", + "@jupyterlab/git": "0.30.0 - 0.40.0", "@jupyterlab/mainmenu": "^3.0.5", "@jupyterlab/nbformat": "^3.0.3", "@jupyterlab/rendermime": "^3.0.6", @@ -70,8 +70,7 @@ "codemirror": "~5.57.0", "json-source-map": "^0.6.1", "moment": "^2.24.0", - "nbdime": "^6.1.0-beta.1", - "nbdime-jupyterlab": "^2.1.0-beta.1", + "nbdime": "^6.1.0", "react": "^17.0.1", "react-dom": "^17.0.1", "react-spinners": "^0.5.12" @@ -133,6 +132,7 @@ "singleton": true }, "nbdime": { + "bundled": false, "singleton": true }, "react": { diff --git a/setup.cfg b/setup.cfg index 3cbf6cb..192b41d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,8 @@ [metadata] long_description = file: README.md long_description_content_type = text/markdown -license-file = LICENSE -description-file = README.md +license_file = LICENSE +description_file = README.md platforms = Linux, Mac OS X, Windows keywords = Interactive @@ -32,7 +32,7 @@ setup_requires = wheel install_requires = jupyterlab ~=3.0 - jupyterlab-git >=0.30.0b3,<0.40.0a0 + jupyterlab-git >=0.30.0,<0.40.0a0 packages = find: include_package_data = True zip_safe = False diff --git a/src/components/ActionButton.tsx b/src/components/ActionButton.tsx new file mode 100644 index 0000000..64b40ca --- /dev/null +++ b/src/components/ActionButton.tsx @@ -0,0 +1,43 @@ +import { LabIcon } from '@jupyterlab/ui-components'; +import * as React from 'react'; + +/** + * Action button properties interface + */ +export interface IActionButtonProps { + /** + * Is disabled? + */ + disabled?: boolean; + /** + * Icon + */ + icon: LabIcon; + /** + * Button title + */ + title: string; + /** + * On-click event handler + */ + onClick?: (event?: React.MouseEvent) => void; +} + +/** + * Action button component + * + * @param props Component properties + */ +export function ActionButton(props: IActionButtonProps): JSX.Element { + const { disabled, title, onClick, icon } = props; + return ( + + ); +} diff --git a/src/components/Toolbar.tsx b/src/components/Toolbar.tsx index a690a0d..a9c08e5 100644 --- a/src/components/Toolbar.tsx +++ b/src/components/Toolbar.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { refreshIcon } from '@jupyterlab/ui-components'; -import { ActionButton } from '@jupyterlab/git/lib/components/ActionButton'; +import { ActionButton } from './ActionButton'; /** * Toolbar properties diff --git a/src/components/browser/PullRequestItem.tsx b/src/components/browser/PullRequestItem.tsx index 70207db..8782edf 100644 --- a/src/components/browser/PullRequestItem.tsx +++ b/src/components/browser/PullRequestItem.tsx @@ -1,5 +1,4 @@ import { DocumentRegistry } from '@jupyterlab/docregistry'; -import { ActionButton } from '@jupyterlab/git/lib/components/ActionButton'; import { caretDownIcon, caretUpIcon, @@ -10,6 +9,7 @@ import React from 'react'; import { BeatLoader } from 'react-spinners'; import { CommandIDs, IFile, IPullRequest } from '../../tokens'; import { requestAPI } from '../../utils'; +import { ActionButton } from '../ActionButton'; import { FileItem } from './FileItem'; /** diff --git a/src/components/diff/NotebookDiff.ts b/src/components/diff/NotebookDiff.ts index 68d2d0e..e55e3b8 100644 --- a/src/components/diff/NotebookDiff.ts +++ b/src/components/diff/NotebookDiff.ts @@ -7,8 +7,9 @@ import { NotebookDiff } from '@jupyterlab/git'; import { DiffModel } from '@jupyterlab/git/lib/components/diff/model'; -import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; +import { INotebookContent } from '@jupyterlab/nbformat'; import jsonMap from 'json-source-map'; +import { IDiffEntry } from 'nbdime/lib/diff/diffentries'; import { CellDiffModel, NotebookDiffModel } from 'nbdime/lib/diff/model'; import { NotebookDiffWidget } from 'nbdime/lib/diff/widget'; import { @@ -17,8 +18,23 @@ import { IThread, IThreadCell } from '../../tokens'; +import { requestAPI } from '../../utils'; import { NotebookCellsDiff } from './NotebookCellsDiff'; +/** + * Data return by the ndbime api endpoint + */ +interface INbdimeDiff { + /** + * Base notebook content + */ + base: INotebookContent; + /** + * Diff to obtain challenger from base + */ + diff: IDiffEntry[]; +} + export class NotebookPRDiff extends NotebookDiff { constructor(props: IDiffOptions) { super( @@ -160,16 +176,22 @@ export class NotebookPRDiff extends NotebookDiff { return threadsByChunk; } - protected createDiffView( - model: NotebookDiffModel, - renderMime: IRenderMimeRegistry - ): NotebookDiffWidget { - // return new NotebookDiffWidget(model, renderMime); + protected async createDiffView( + challengerContent: string, + referenceContent: string + ): Promise { + const data = await requestAPI('git/diffnotebook', 'POST', { + currentContent: challengerContent, + previousContent: referenceContent + }); + + const model = new NotebookDiffModel(data.base, data.diff); + const baseMapping = Private.computeNotebookMapping( - this._props.diff.base.content || '{}' + referenceContent || '{}' ); const headMapping = Private.computeNotebookMapping( - this._props.diff.head.content || '{}' + challengerContent || '{}' ); const comments = NotebookPRDiff.mapThreadsOnChunks( baseMapping, @@ -183,7 +205,7 @@ export class NotebookPRDiff extends NotebookDiff { filename: this._props.filename, model, comments, - renderMime + renderMime: this._props.renderMime }); } diff --git a/src/components/diff/plaintext.ts b/src/components/diff/plaintext.ts index af0debb..ca43905 100644 --- a/src/components/diff/plaintext.ts +++ b/src/components/diff/plaintext.ts @@ -2,7 +2,7 @@ import { PlainTextDiff } from '@jupyterlab/git'; import { DiffModel } from '@jupyterlab/git/lib/components/diff/model'; import { Widget } from '@lumino/widgets'; -import { LineWidget } from 'codemirror'; +import { LineWidget, MergeView } from 'codemirror'; import { IComment, IDiffOptions, IThread } from '../../tokens'; import { generateNode } from '../../utils'; import { Discussion } from '../discussion/Discussion'; @@ -101,22 +101,17 @@ export class PlainTextPRDiff extends PlainTextDiff { editor.setGutterMarker(lineIdx, 'jp-PullRequestCommentDecoration', div); } } - /** * Create the Plain Text Diff view */ - protected async createDiffView(): Promise { - await super.createDiffView(); + protected async createDiffView( + challengerContent: string, + referenceContent: string + ): Promise { + await super.createDiffView(challengerContent, referenceContent); if (this._mergeView) { { - this._mergeView.leftOriginal().setOption('gutters', [ - 'CodeMirror-linenumbers', - // FIXME without this - the comment decoration does not show up - // But it add a single comment decoration on the first line of each editors - 'jp-PullRequestCommentDecoration', - 'CodeMirror-patchgutter' - ]); const { from, to } = this._mergeView.leftOriginal().getViewport(); this.updateView( this._mergeView.leftOriginal(), @@ -135,13 +130,6 @@ export class PlainTextPRDiff extends PlainTextDiff { } { - this._mergeView.editor().setOption('gutters', [ - 'CodeMirror-linenumbers', - // FIXME without this - the comment decoration does not show up - // But it add a single comment decoration on the first line of each editors - 'jp-PullRequestCommentDecoration', - 'CodeMirror-patchgutter' - ]); const { from, to } = this._mergeView.editor().getViewport(); this.updateView(this._mergeView.editor(), from, to, 'line'); this._mergeView @@ -194,6 +182,24 @@ export class PlainTextPRDiff extends PlainTextDiff { } } + /** + * Returns default CodeMirror editor options + * + * @returns CodeMirror editor options + */ + protected getDefaultOptions(): Partial { + return { + ...super.getDefaultOptions(), + gutters: [ + 'CodeMirror-linenumbers', + // without this - the comment decoration does not show up + // But it add a single comment decoration on the first line of each editors + 'jp-PullRequestCommentDecoration', + 'CodeMirror-patchgutter' + ] + }; + } + /** * Create the widget associated with a discussion * diff --git a/style/base.css b/style/base.css index ea50d0c..e751c4c 100644 --- a/style/base.css +++ b/style/base.css @@ -1,7 +1,6 @@ /*----------------------------------------------------------------------------- | JupyterLab Pull Requests Style |----------------------------------------------------------------------------*/ -@import url('~@jupyterlab/git/style/index.css'); .jp-PullRequestPanel { height: 100%; @@ -10,6 +9,26 @@ background-color: var(--jp-layout-color0); } +.jp-PullRequestButton { + flex: 0 0 auto; + background: none; + line-height: 0px; + padding: 0px 4px; + width: 16px; + border: none; + outline: none; + cursor: pointer; +} + +.jp-PullRequestButton:active { + transform: scale(1.272019649); + overflow: hidden; +} + +.jp-PullRequestButton:disabled { + cursor: default; +} + .jp-PullRequestToolbar { flex: 0 0 auto; border-bottom: none; diff --git a/yarn.lock b/yarn.lock index 36421f3..bfee095 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1483,10 +1483,10 @@ "@lumino/widgets" "^1.16.1" react "^17.0.1" -"@jupyterlab/git@0.30.0-beta.3 - 0.40.0": - version "0.30.0-beta.3" - resolved "https://registry.yarnpkg.com/@jupyterlab/git/-/git-0.30.0-beta.3.tgz#ddc9cd29d9a8c1e8ed488e8d0b34fe3babce24c5" - integrity sha512-jgUWXj2OQGxXTDuUIXbZZgfLF3wUHp8WyTMf4CRHu6kNtek2Uyrp/ScdMiD0dO5yYnkSAN2iiELFlzFfFrEnSw== +"@jupyterlab/git@0.30.0 - 0.40.0": + version "0.30.0" + resolved "https://registry.yarnpkg.com/@jupyterlab/git/-/git-0.30.0.tgz#12b80050283bcabfa09ec2ee2813f93b91c88836" + integrity sha512-e0TXn8sApwliaUjEVRCVYISft85dJKg7BBdsWY5ghHvjtLjrh26h4Fx9dcDr+Np/Kjrr/i/8gTUUmA/ZBU0kDQ== dependencies: "@jupyterlab/application" "^3.0.0" "@jupyterlab/apputils" "^3.0.0" @@ -1514,7 +1514,8 @@ "@material-ui/icons" "^4.5.1" "@material-ui/lab" "^4.0.0-alpha.54" diff-match-patch "^1.0.4" - nbdime "^6.1.0-beta.1" + nbdime "^6.1.0" + nbdime-jupyterlab "^2.1.0" react "^17.0.1" react-dom "^17.0.1" react-textarea-autosize "^7.1.2" @@ -6348,10 +6349,10 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -nbdime-jupyterlab@2.1.0-beta.1: - version "2.1.0-beta.1" - resolved "https://registry.yarnpkg.com/nbdime-jupyterlab/-/nbdime-jupyterlab-2.1.0-beta.1.tgz#9b650bd044e94bec24e8ac80b1f25616fd669851" - integrity sha512-4QTXnQbSJMbFVnNM35lcrDFLmYF8UCVLa2kUFcEKzsp5gHgQ+zRtxOq0aS4hLI26p394wzAuME24k8bnk2PvaA== +nbdime-jupyterlab@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/nbdime-jupyterlab/-/nbdime-jupyterlab-2.1.0.tgz#3b7ebe2ce65f02038f86ceab4df9f705d315dc16" + integrity sha512-aZdMumdglw9S0JDVm6WVLOadGQyWOmPetpk8SGN4CEJ5mL9is1siLLkEI4diQWFFzDXzNkkh1KEfgJpmRLIemg== dependencies: "@jupyterlab/apputils" "^2 || ^3" "@jupyterlab/coreutils" "^4 || ^5" @@ -6364,12 +6365,12 @@ nbdime-jupyterlab@2.1.0-beta.1: "@lumino/coreutils" "^1.3.0" "@lumino/disposable" "^1.1.2" "@lumino/widgets" "^1.6.0" - nbdime "^6.1.0-beta.1" + nbdime "^6.1.0" -nbdime@^6.1.0-beta.1: - version "6.1.0-beta.1" - resolved "https://registry.yarnpkg.com/nbdime/-/nbdime-6.1.0-beta.1.tgz#3b925f1ef3f028a25ae851e5cd5e7f3c50fc2304" - integrity sha512-Rrap6tRT1GDT4OZ1dbt3FG9oWA458LvuTKqR0zkdzREg1pGnkidpVshE7xoPsshpCXmRrqvGOQG3lSSygFPnDA== +nbdime@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/nbdime/-/nbdime-6.1.0.tgz#d8d0e89c22ae888d024985405f9bf388c8ebb0d5" + integrity sha512-bJHS2kF87kswm/5jphl9TCB6HGJcTUf4FViIliLUexZ3Vpmu97Dr2O1t9psHsMWT13wEUgzqHsLwg6EnnU+Fug== dependencies: "@jupyterlab/codeeditor" "^2 || ^3" "@jupyterlab/codemirror" "^2 || ^3"