Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to JLab 3.1 #979

Merged
merged 4 commits into from
Aug 16, 2021
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
10 changes: 9 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ var tsOptions = tsConfig['compilerOptions'];
tsOptions['rootDir'] = null;
tsOptions['inlineSourceMap'] = true;

const esModules = [
'.*@jupyterlab/',
'lib0',
'y\\-protocols',
'y\\-websocket',
'yjs'
].join('|');

module.exports = {
automock: false,
moduleNameMapper: {
Expand All @@ -20,7 +28,7 @@ module.exports = {
setupFiles: ['<rootDir>/testutils/jest-setup-files.js'],
testPathIgnorePatterns: ['/lib/', '/node_modules/', '/jupyterlab_git/'],
testRegex: '/tests/.*.spec.ts[x]?$',
transformIgnorePatterns: ['/node_modules/(?!(@jupyterlab/.*)/)'],
transformIgnorePatterns: [`/node_modules/(?!${esModules}).+`],
globals: {
'ts-jest': {
tsconfig: tsOptions
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"@lumino/commands": "^1.12.0",
"@lumino/coreutils": "^1.5.3",
"@lumino/disposable": "^1.4.3",
"@lumino/messaging": "^1.7.1",
"@lumino/polling": "^1.3.3",
"@lumino/signaling": "^1.4.3",
"@lumino/widgets": "^1.17.0",
Expand Down
84 changes: 83 additions & 1 deletion schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,87 @@
"keys": ["Accel Enter"],
"selector": ".jp-git-CommitBox"
}
]
],
"jupyter.lab.menus": {
"main": [
{
"id": "jp-mainmenu-git",
"label": "Git",
"rank": 60,
"items": [
{
"command": "git:init"
},
{
"command": "git:clone"
},
{
"command": "git:push"
},
{
"command": "git:pull"
},
{
"command": "git:add-remote"
},
{
"command": "git:terminal-command"
},
{
"type": "separator"
},
{
"command": "git:toggle-simple-staging"
},
{
"command": "git:toggle-double-click-diff"
},
{
"type": "separator"
},
{
"command": "git:open-gitignore"
},
{
"type": "separator"
},
{
"type": "submenu",
"submenu": {
"id": "jp-mainmenu-git-help",
"label": "Help",
"items": [
{
"command": "git:open-url",
"args": {
"text": "Set Up Remotes",
"url": "https://www.atlassian.com/git/tutorials/setting-up-a-repository"
}
},
{
"command": "git:open-url",
"args": {
"text": "Git Documentation",
"url": "https://git-scm.com/doc"
}
}
]
}
}
]
}
],
"context": [
{
"type": "submenu",
"selector": ".jp-DirListing-item[data-isdir=\"false\"]",
"rank": 5,
"submenu": {
"id": "jp-contextmenu-git",
"label": "Git",
"icon": "git"
}
}
]
}
}
219 changes: 118 additions & 101 deletions src/commandsAndMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { ArrayExt, toArray } from '@lumino/algorithm';
import { CommandRegistry } from '@lumino/commands';
import { PromiseDelegate } from '@lumino/coreutils';
import { Message } from '@lumino/messaging';
import { Menu, Panel } from '@lumino/widgets';
import { ContextMenu, Menu, Panel } from '@lumino/widgets';
import * as React from 'react';
import { DiffModel } from './components/diff/model';
import { createPlainTextDiff } from './components/diff/PlainTextDiff';
Expand Down Expand Up @@ -988,9 +988,6 @@ export function createGitMenu(
return menu;
}

// matches only non-directory items
const selectorNotDir = '.jp-DirListing-item[data-isdir="false"]';

export function addMenuItems(
commands: ContextCommandIDs[],
contextMenu: Menu,
Expand Down Expand Up @@ -1022,12 +1019,11 @@ export function addMenuItems(
}

/**
* Add Git context (sub)menu to the file browser context menu.
* Populate Git context submenu depending on the selected files.
*/
export function addFileBrowserContextMenu(
model: IGitExtension,
tracker: WidgetTracker<FileBrowser>,
commands: CommandRegistry,
contextMenu: ContextMenuSvg
): void {
function getSelectedBrowserItems(): Contents.IModel[] {
Expand All @@ -1038,112 +1034,133 @@ export function addFileBrowserContextMenu(
return toArray(widget.selectedItems());
}

class GitMenu extends Menu {
private _commands: ContextCommandIDs[];
private _paths: string[];

protected onBeforeAttach(msg: Message) {
// Render using the most recent model (even if possibly outdated)
this.updateItems();
const renderedStatus = model.status;

// Trigger refresh before the menu is displayed
model
.refreshStatus()
.then(() => {
if (model.status !== renderedStatus) {
// update items if needed
this.updateItems();
}
})
.catch(error => {
console.error(
'Fail to refresh model when displaying git context menu.',
error
);
});
super.onBeforeAttach(msg);
}

protected updateItems(): void {
const wasShown = this.isVisible;
const parent = this.parentMenu;

const items = getSelectedBrowserItems();
const statuses = new Set<Git.Status>(
items.map(item => model.getFile(item.path).status)
);

// get commands and de-duplicate them
const allCommands = new Set<ContextCommandIDs>(
// flatten the list of lists of commands
[]
.concat(...[...statuses].map(status => CONTEXT_COMMANDS[status]))
// filter out the Open and Delete commands as
// those are not needed in file browser
.filter(
command =>
command !== ContextCommandIDs.gitFileOpen &&
command !== ContextCommandIDs.gitFileDelete &&
typeof command !== 'undefined'
)
// replace stage and track with a single "add" operation
.map(command =>
command === ContextCommandIDs.gitFileStage ||
command === ContextCommandIDs.gitFileTrack
? ContextCommandIDs.gitFileAdd
: command
)
let gitMenu: Menu;
let _commands: ContextCommandIDs[];
let _paths: string[];

function updateItems(menu: Menu): void {
const wasShown = menu.isVisible;
const parent = menu.parentMenu;

const items = getSelectedBrowserItems();
const statuses = new Set<Git.Status>(
items
.map(item => model.getFile(item.path)?.status)
.filter(status => typeof status !== 'undefined')
);

// get commands and de-duplicate them
const allCommands = new Set<ContextCommandIDs>(
// flatten the list of lists of commands
[]
.concat(...[...statuses].map(status => CONTEXT_COMMANDS[status]))
// filter out the Open and Delete commands as
// those are not needed in file browser
.filter(
command =>
command !== ContextCommandIDs.gitFileOpen &&
command !== ContextCommandIDs.gitFileDelete &&
typeof command !== 'undefined'
)
// replace stage and track with a single "add" operation
.map(command =>
command === ContextCommandIDs.gitFileStage ||
command === ContextCommandIDs.gitFileTrack
? ContextCommandIDs.gitFileAdd
: command
)
);

const commandsChanged =
!_commands ||
_commands.length !== allCommands.size ||
!_commands.every(command => allCommands.has(command));

const paths = items.map(item => item.path);

const filesChanged = !_paths || !ArrayExt.shallowEqual(_paths, paths);

if (commandsChanged || filesChanged) {
const commandsList = [...allCommands];
menu.clearItems();
addMenuItems(
commandsList,
menu,
paths
.map(path => model.getFile(path))
// if file cannot be resolved (has no action available),
// omit the undefined result
.filter(file => typeof file !== 'undefined')
);

// if looking at a tracked file without any actions available
// (although `git rm` would be a valid action)
if (allCommands.size === 0) {
allCommands.add(ContextCommandIDs.gitNoAction);
if (wasShown) {
// show the menu again after downtime for refresh
parent.triggerActiveItem();
}
_commands = commandsList;
_paths = paths;
}
}

const commandsChanged =
!this._commands ||
this._commands.length !== allCommands.size ||
!this._commands.every(command => allCommands.has(command));

const paths = items.map(item => item.path);
function updateGitMenu(contextMenu: ContextMenu) {
if (!gitMenu) {
gitMenu =
contextMenu.menu.items.find(
item =>
item.type === 'submenu' && item.submenu?.id === 'jp-contextmenu-git'
)?.submenu ?? null;
}

const filesChanged =
!this._paths || !ArrayExt.shallowEqual(this._paths, paths);
if (!gitMenu) {
return; // Bail early if the open with menu is not displayed
}

if (commandsChanged || filesChanged) {
const commandsList = [...allCommands];
this.clearItems();
addMenuItems(
commandsList,
this,
paths.map(path => model.getFile(path))
);
if (wasShown) {
// show the menu again after downtime for refresh
parent.triggerActiveItem();
// Render using the most recent model (even if possibly outdated)
updateItems(gitMenu);
const renderedStatus = model.status;

// Trigger refresh before the menu is displayed
model
.refreshStatus()
.then(() => {
if (model.status !== renderedStatus) {
// update items if needed
updateItems(gitMenu);
}
this._commands = commandsList;
this._paths = paths;
}
}
})
.catch(error => {
console.error(
'Fail to refresh model when displaying git context menu.',
error
);
});
}

onBeforeShow(msg: Message): void {
super.onBeforeShow(msg);
// as any is to support JLab 3.1 feature
if ((contextMenu as any).opened) {
(contextMenu as any).opened.connect(updateGitMenu);
} else {
// matches only non-directory items

class GitMenu extends Menu {
protected onBeforeAttach(msg: Message): void {
updateGitMenu(contextMenu);
super.onBeforeAttach(msg);
}
}
}

const gitMenu = new GitMenu({ commands });
gitMenu.title.label = 'Git';
gitMenu.title.icon = gitIcon.bindprops({ stylesheet: 'menuItem' });
const selectorNotDir = '.jp-DirListing-item[data-isdir="false"]';
gitMenu = new GitMenu({ commands: contextMenu.menu.commands });
gitMenu.title.label = 'Git';
gitMenu.title.icon = gitIcon.bindprops({ stylesheet: 'menuItem' });

contextMenu.addItem({
type: 'submenu',
submenu: gitMenu,
selector: selectorNotDir,
rank: 5
});
contextMenu.addItem({
type: 'submenu',
submenu: gitMenu,
selector: selectorNotDir,
rank: 5
});
}
}

/* eslint-disable no-inner-declarations */
Expand Down
2 changes: 2 additions & 0 deletions src/components/diff/NotebookDiff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ export class NotebookDiff extends Panel implements Git.Diff.IDiffWidget {

const model = new NotebookDiffModel(data.base, data.diff);

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return new NotebookDiffWidget(model, this._renderMime);
}

Expand Down
Loading