Merge pull request #18 from jtpio/tree-tabpanel

Combine running and file browser on tree
pull/6294/head
Jeremy Tuloup 5 years ago committed by GitHub
commit b659326bd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -106,17 +106,12 @@ async function main() {
const page = PageConfig.getOption('classicPage');
if (page === 'tree') {
mods = mods.concat([
require('@jupyterlab-classic/filebrowser-extension').default.filter(
({ id }) =>
[
'@jupyterlab-classic/filebrowser-extension:browser',
'@jupyterlab-classic/filebrowser-extension:factory'
].includes(id)
)
]);
} else if (page === 'running') {
mods = mods.concat([
require('@jupyterlab-classic/running-extension'),
require('@jupyterlab-classic/tree-extension').default.filter(({ id }) =>
[
'@jupyterlab-classic/tree-extension:browser',
'@jupyterlab-classic/tree-extension:factory'
].includes(id)
),
require('@jupyterlab/running-extension')
]);
} else if (page === 'notebooks') {

@ -13,9 +13,8 @@
"@jupyterlab-classic/application": "^0.1.0",
"@jupyterlab-classic/application-extension": "^0.1.0",
"@jupyterlab-classic/docmanager-extension": "^0.1.0",
"@jupyterlab-classic/filebrowser-extension": "^0.1.0",
"@jupyterlab-classic/notebook-extension": "^0.1.0",
"@jupyterlab-classic/running-extension": "^0.1.0",
"@jupyterlab-classic/tree-extension": "^0.1.0",
"@jupyterlab-classic/ui-components": "^0.1.0",
"@jupyterlab/apputils-extension": "^3.0.0-rc.12",
"@jupyterlab/codemirror-extension": "^3.0.0-rc.12",

@ -1,7 +1,6 @@
@import url('~@jupyterlab-classic/application-extension/style/index.css');
@import url('~@jupyterlab-classic/filebrowser-extension/style/index.css');
@import url('~@jupyterlab-classic/notebook-extension/style/index.css');
@import url('~@jupyterlab-classic/running-extension/style/index.css');
@import url('~@jupyterlab-classic/tree-extension/style/index.css');
@import url('~@jupyterlab-classic/ui-components/style/index.css');
/* TODO: check is the the extension package can be used directly */

@ -87,20 +87,6 @@ class ClassicTreeHandler(ClassicPageConfigMixin, ExtensionHandlerJinjaMixin, Ext
)
class ClassicRunningHandler(ClassicPageConfigMixin, ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler):
@web.authenticated
def get(self, path=None):
page_config = self.get_page_config()
return self.write(
self.render_template(
"running.html",
base_url=self.base_url,
token=self.settings["token"],
page_config=page_config,
)
)
class ClassicNotebookHandler(ClassicPageConfigMixin, ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler):
@web.authenticated
def get(self, path=None):
@ -131,7 +117,6 @@ class ClassicApp(NBClassicConfigShimMixin, LabServerApp):
def initialize_handlers(self):
super().initialize_handlers()
self.handlers.append(("/classic/tree(.*)", ClassicTreeHandler))
self.handlers.append(("/classic/running", ClassicRunningHandler))
self.handlers.append(("/classic/notebooks(.*)", ClassicNotebookHandler))
def initialize_templates(self):

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{page_config['appName'] | e}} - Running Sessions</title>
</head>
<body>
{# Copy so we do not modify the page_config with updates. #}
{% set page_config_full = page_config.copy() %}
{# Set a dummy variable - we just want the side effect of the update. #}
{% set _ = page_config_full.update(baseUrl=base_url, wsUrl=ws_url) %}
{# Sentinel value to say that we are on the tree page #}
{% set _ = page_config_full.update(classicPage='running') %}
<script id="jupyter-config-data" type="application/json">
{{ page_config_full | tojson }}
</script>
<script src="{{page_config['fullStaticUrl'] | e}}/bundle.js" main="index"></script>
<script type="text/javascript">
/* Remove token from URL. */
(function () {
var parsedUrl = new URL(window.location.href);
if (parsedUrl.searchParams.get('token')) {
parsedUrl.searchParams.delete('token');
window.history.replaceState({ }, '', parsedUrl.href);
}
})();
</script>
</body>
</html>

@ -54,11 +54,6 @@ namespace CommandIDs {
* Open the tree page.
*/
export const openTree = 'application:open-tree';
/**
* Open the runnning page.
*/
export const openRunning = 'application:open-running';
}
/**
@ -120,34 +115,21 @@ const pages: JupyterFrontEndPlugin<void> = {
});
app.commands.addCommand(CommandIDs.openTree, {
label: 'Open the File Browser',
label: 'Open File Browser',
execute: () => {
window.open(`${baseUrl}classic/tree`);
}
});
app.commands.addCommand(CommandIDs.openRunning, {
label: 'Open the Running Sessions',
execute: () => {
window.open(`${baseUrl}classic/running`);
}
});
if (palette) {
[CommandIDs.openLab, CommandIDs.openRunning, CommandIDs.openTree].forEach(
command => {
palette.addItem({ command, category: 'View' });
}
);
[CommandIDs.openLab, CommandIDs.openTree].forEach(command => {
palette.addItem({ command, category: 'View' });
});
}
if (menu) {
menu.viewMenu.addGroup(
[
{ command: CommandIDs.openLab },
{ command: CommandIDs.openTree },
{ command: CommandIDs.openRunning }
],
[{ command: CommandIDs.openLab }, { command: CommandIDs.openTree }],
0
);
}

@ -1,3 +0,0 @@
.jp-FileBrowser {
height: 100%;
}

@ -19,6 +19,7 @@
}
.jp-ClassicKernelStatus {
/* TODO: replace with lab variable */
font-size: 12px;
margin: 0;
font-weight: normal;

@ -1,53 +0,0 @@
{
"name": "@jupyterlab-classic/running-extension",
"version": "0.1.0",
"description": "JupyterLab Classic - Running Extension",
"homepage": "https://github.com/jtpio/jupyterlab-classic",
"bugs": {
"url": "https://github.com/jtpio/jupyterlab-classic/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/jtpio/jupyterlab-classic.git"
},
"license": "BSD-3-Clause",
"author": "Project Jupyter",
"sideEffects": [
"style/**/*.css"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"style": "style/index.css",
"directories": {
"lib": "lib/"
},
"files": [
"lib/*.d.ts",
"lib/*.js.map",
"lib/*.js",
"schema/*.json",
"style/**/*.css"
],
"scripts": {
"build": "tsc -b",
"clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
"docs": "typedoc src",
"prepublishOnly": "npm run build",
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.0.0-rc.12",
"@jupyterlab/running": "^3.0.0-rc.12",
"@jupyterlab/translation": "^3.0.0-rc.12"
},
"devDependencies": {
"rimraf": "~3.0.0",
"typescript": "~4.0.2"
},
"publishConfig": {
"access": "public"
},
"jupyterlab": {
"extension": true
}
}

@ -1,36 +0,0 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { IRunningSessionManagers, RunningSessions } from '@jupyterlab/running';
import { ITranslator } from '@jupyterlab/translation';
/**
* The default running sessions extension.
*/
const plugin: JupyterFrontEndPlugin<void> = {
id: '@jupyterlab-classic/running-extension:plugin',
requires: [IRunningSessionManagers],
autoStart: true,
activate: (
app: JupyterFrontEnd,
manager: IRunningSessionManagers,
translator: ITranslator
): void => {
const running = new RunningSessions(manager, translator);
running.id = 'jp-running-sessions';
// re-add the widget to the main area
app.shell.add(running, 'main');
}
};
/**
* Export the plugin as default.
*/
export default plugin;

@ -1,3 +0,0 @@
.jp-RunningSessions {
height: 100%;
}

@ -1,3 +0,0 @@
@import url('~@jupyterlab/running/style/index.css');
@import url('./base.css');

@ -1,8 +0,0 @@
{
"extends": "../../tsconfigbase",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
},
"include": ["src/**/*"]
}

@ -1,7 +1,7 @@
{
"name": "@jupyterlab-classic/filebrowser-extension",
"name": "@jupyterlab-classic/tree-extension",
"version": "0.1.0",
"description": "JupyterLab Classic - File browser Extension",
"description": "JupyterLab Classic - Tree Extension",
"homepage": "https://github.com/jtpio/jupyterlab-classic",
"bugs": {
"url": "https://github.com/jtpio/jupyterlab-classic/issues"
@ -42,7 +42,6 @@
"@jupyterlab/coreutils": "^5.0.0-rc.13",
"@jupyterlab/docmanager": "^3.0.0-rc.13",
"@jupyterlab/filebrowser": "^3.0.0-rc.13",
"@jupyterlab/launcher": "^3.0.0-rc.13",
"@jupyterlab/mainmenu": "^3.0.0-rc.13",
"@jupyterlab/services": "^6.0.0-rc.13",
"@jupyterlab/settingregistry": "^3.0.0-rc.13",
@ -51,7 +50,6 @@
"@jupyterlab/ui-components": "^3.0.0-rc.13",
"@lumino/algorithm": "^1.3.3",
"@lumino/commands": "^1.12.0",
"@lumino/messaging": "^1.4.3",
"@lumino/widgets": "^1.16.1"
},
"devDependencies": {

@ -6,7 +6,6 @@
// Distributed under the terms of the Modified BSD License.
import {
ILabShell,
ILayoutRestorer,
ITreePathUpdater,
IRouter,
@ -16,8 +15,6 @@ import {
import {
Clipboard,
MainAreaWidget,
ToolbarButton,
WidgetTracker,
ICommandPalette,
InputDialog,
@ -25,7 +22,7 @@ import {
DOMUtils
} from '@jupyterlab/apputils';
import { PageConfig, PathExt } from '@jupyterlab/coreutils';
import { PathExt } from '@jupyterlab/coreutils';
import { IDocumentManager } from '@jupyterlab/docmanager';
@ -35,10 +32,10 @@ import {
IFileBrowserFactory
} from '@jupyterlab/filebrowser';
import { Launcher } from '@jupyterlab/launcher';
import { IMainMenu } from '@jupyterlab/mainmenu';
import { IRunningSessionManagers, RunningSessions } from '@jupyterlab/running';
import { Contents } from '@jupyterlab/services';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
@ -59,17 +56,16 @@ import {
markdownIcon,
newFolderIcon,
pasteIcon,
runningIcon,
stopIcon,
textEditorIcon
} from '@jupyterlab/ui-components';
import { IIterator, map, reduce, toArray, find } from '@lumino/algorithm';
import { map, toArray } from '@lumino/algorithm';
import { CommandRegistry } from '@lumino/commands';
import { Message } from '@lumino/messaging';
import { Menu } from '@lumino/widgets';
import { TabPanel } from '@lumino/widgets';
/**
* The command IDs used by the file browser plugin.
@ -79,9 +75,6 @@ namespace CommandIDs {
export const copyDownloadLink = 'filebrowser:copy-download-link';
// For main browser only.
export const createLauncher = 'filebrowser:create-main-launcher';
export const cut = 'filebrowser:cut';
export const del = 'filebrowser:delete';
@ -90,9 +83,6 @@ namespace CommandIDs {
export const duplicate = 'filebrowser:duplicate';
// For main browser only.
export const hideBrowser = 'filebrowser:hide-main';
export const goToPath = 'filebrowser:go-to-path';
export const openPath = 'filebrowser:open-path';
@ -117,13 +107,8 @@ namespace CommandIDs {
// For main browser only.
export const copyPath = 'filebrowser:copy-path';
export const showBrowser = 'filebrowser:activate';
export const shutdown = 'filebrowser:shutdown';
// For main browser only.
export const toggleBrowser = 'filebrowser:toggle-main';
export const toggleNavigateToCurrentDirectory =
'filebrowser:toggle-navigate-to-current-directory';
@ -137,7 +122,7 @@ namespace CommandIDs {
*/
const browser: JupyterFrontEndPlugin<void> = {
activate: activateBrowser,
id: '@jupyterlab-classic/filebrowser-extension:browser',
id: '@jupyterlab-classic/tree-extension:browser',
requires: [
IFileBrowserFactory,
IDocumentManager,
@ -145,24 +130,26 @@ const browser: JupyterFrontEndPlugin<void> = {
ITranslator
],
optional: [
ILabShell,
ICommandPalette,
IMainMenu,
ILayoutRestorer,
ITreePathUpdater
ITreePathUpdater,
IRunningSessionManagers
],
autoStart: true
};
/**
* The default file browser factory provider.
*
* TODO: remove and use upstream plugin
*/
const factory: JupyterFrontEndPlugin<IFileBrowserFactory> = {
activate: activateFactory,
id: '@jupyterlab-classic/filebrowser-extension:factory',
id: '@jupyterlab-classic/tree-extension:factory',
provides: IFileBrowserFactory,
requires: [IDocumentManager, ITranslator],
optional: [ILabShell, IStateDB, IRouter, JupyterFrontEnd.ITreeResolver]
optional: [IStateDB, IRouter, JupyterFrontEnd.ITreeResolver]
};
/**
@ -183,12 +170,10 @@ async function activateFactory(
app: JupyterFrontEnd,
docManager: IDocumentManager,
translator: ITranslator,
labShell: ILabShell | null,
state: IStateDB | null,
router: IRouter | null,
tree: JupyterFrontEnd.ITreeResolver | null
): Promise<IFileBrowserFactory> {
const trans = translator.load('jupyterlab');
const { commands } = app;
const tracker = new WidgetTracker<FileBrowser>({ namespace });
const createFileBrowser = (
@ -207,31 +192,6 @@ async function activateFactory(
const restore = options.restore;
const widget = new FileBrowser({ id, model, restore, translator });
// Add a launcher toolbar item.
if (labShell) {
const launcher = new ToolbarButton({
icon: addIcon,
onClick: () => {
if (
labShell.mode === 'multiple-document' &&
commands.hasCommand('launcher:create')
) {
return Private.createLauncher(commands, widget);
} else {
const newUrl = PageConfig.getUrl({
mode: labShell.mode,
workspace: PageConfig.defaultWorkspace,
treePath: model.path
});
window.open(newUrl, '_blank');
}
},
tooltip: trans.__('New Launcher'),
actualOnClick: true
});
widget.toolbar.insertItem(0, 'launch', launcher);
}
// Track the newly created file browser.
void tracker.add(widget);
@ -257,15 +217,13 @@ function activateBrowser(
docManager: IDocumentManager,
settingRegistry: ISettingRegistry,
translator: ITranslator,
labShell: ILabShell | null,
commandPalette: ICommandPalette | null,
mainMenu: IMainMenu | null,
restorer: ILayoutRestorer | null,
treePathUpdater: ITreePathUpdater | null
treePathUpdater: ITreePathUpdater | null,
manager: IRunningSessionManagers | null
): void {
const trans = translator.load('jupyterlab');
const browser = factory.defaultBrowser;
const { commands } = app;
// Let the application restorer track the primary file browser (that is
// automatically created) for restoration of application state (e.g. setting
@ -282,60 +240,31 @@ function activateBrowser(
factory,
settingRegistry,
translator,
labShell,
commandPalette,
mainMenu
);
browser.title.icon = folderIcon;
// Show the current file browser shortcut in its title.
const updateBrowserTitle = () => {
const binding = find(
app.commands.keyBindings,
b => b.command === CommandIDs.toggleBrowser
);
if (binding) {
const ks = CommandRegistry.formatKeystroke(binding.keys.join(' '));
browser.title.caption = trans.__('File Browser (%1)', ks);
} else {
browser.title.caption = trans.__('File Browser');
}
};
updateBrowserTitle();
app.commands.keyBindingChanged.connect(() => {
updateBrowserTitle();
});
app.shell.add(browser, 'main', { rank: 100 });
const tabPanel = new TabPanel({ tabPlacement: 'top', tabsMovable: true });
tabPanel.addClass('jp-TreePanel');
// If the layout is a fresh session without saved data and not in single document
// mode, open file browser.
if (labShell) {
void labShell.restored.then(layout => {
if (layout.fresh && labShell.mode !== 'single-document') {
void commands.execute(CommandIDs.showBrowser, void 0);
}
});
}
browser.title.label = 'File Browser';
tabPanel.addWidget(browser);
tabPanel.tabBar.addTab(browser.title);
void Promise.all([app.restored, browser.model.restored]).then(() => {
function maybeCreate() {
// Create a launcher if there are no open items.
if (
toArray(app.shell.widgets('main')).length === 0 &&
commands.hasCommand('launcher:create')
) {
void Private.createLauncher(commands, browser);
}
}
if (manager) {
const running = new RunningSessions(manager, translator);
running.id = 'jp-running-sessions';
running.title.label = 'Running Sessions';
running.title.icon = runningIcon;
tabPanel.addWidget(running);
tabPanel.tabBar.addTab(running.title);
}
// When layout is modified, create a launcher if there are no open items.
if (labShell) {
labShell.layoutModified.connect(() => {
maybeCreate();
});
}
app.shell.add(tabPanel, 'main', { rank: 100 });
void Promise.all([app.restored, browser.model.restored]).then(() => {
let navigateToCurrentDirectory = false;
let useFuzzyFilter = true;
@ -359,35 +288,11 @@ function activateBrowser(
browser.useFuzzyFilter = useFuzzyFilter;
});
// Whether to automatically navigate to a document's current directory
if (labShell) {
labShell.currentChanged.connect(async (_, change) => {
if (navigateToCurrentDirectory && change.newValue) {
const { newValue } = change;
const context = docManager.contextForWidget(newValue);
if (context) {
const { path } = context;
try {
await Private.navigateToPath(path, factory, translator);
labShell.currentWidget?.activate();
} catch (reason) {
console.warn(
`${CommandIDs.goToPath} failed to open: ${path}`,
reason
);
}
}
}
});
}
if (treePathUpdater) {
browser.model.pathChanged.connect((sender, args) => {
treePathUpdater(args.newValue);
});
}
maybeCreate();
});
}
@ -399,7 +304,6 @@ function addCommands(
factory: IFileBrowserFactory,
settingRegistry: ISettingRegistry,
translator: ITranslator,
labShell: ILabShell | null,
commandPalette: ICommandPalette | null,
mainMenu: IMainMenu | null
): void {
@ -469,24 +373,12 @@ function addCommands(
label: trans.__('Duplicate')
});
if (labShell) {
commands.addCommand(CommandIDs.hideBrowser, {
execute: () => {
const widget = tracker.currentWidget;
if (widget && !widget.isHidden) {
labShell.collapseLeft();
}
}
});
}
commands.addCommand(CommandIDs.goToPath, {
execute: async args => {
const path = (args.path as string) || '';
const showBrowser = !(args?.dontShowBrowser ?? false);
try {
const item = await Private.navigateToPath(path, factory, translator);
if (item.type !== 'directory' && showBrowser) {
if (item.type !== 'directory') {
const browserForPath = Private.getBrowserForPath(path, factory);
if (browserForPath) {
browserForPath.clearSelectedItems();
@ -500,9 +392,6 @@ function addCommands(
} catch (reason) {
console.warn(`${CommandIDs.goToPath} failed to go to: ${path}`, reason);
}
if (showBrowser) {
return commands.execute(CommandIDs.showBrowser, { path });
}
}
});
@ -740,36 +629,6 @@ function addCommands(
label: trans.__('Copy Path')
});
commands.addCommand(CommandIDs.showBrowser, {
execute: args => {
const path = (args.path as string) || '';
const browserForPath = Private.getBrowserForPath(path, factory);
// Check for browser not found
if (!browserForPath) {
return;
}
// Shortcut if we are using the main file browser
if (browser === browserForPath) {
app.shell.activateById(browser.id);
return;
} else {
const areas: ILabShell.Area[] = ['left', 'right'];
for (const area of areas) {
const it = app.shell.widgets(area);
let widget = it.next();
while (widget) {
if (widget.contains(browserForPath)) {
app.shell.activateById(widget.id);
return;
}
widget = it.next();
}
}
}
}
});
commands.addCommand(CommandIDs.shutdown, {
execute: () => {
const widget = tracker.currentWidget;
@ -782,21 +641,6 @@ function addCommands(
label: trans.__('Shut Down Kernel')
});
commands.addCommand(CommandIDs.toggleBrowser, {
execute: () => {
if (browser.isHidden) {
return commands.execute(CommandIDs.showBrowser, void 0);
}
return commands.execute(CommandIDs.hideBrowser, void 0);
}
});
commands.addCommand(CommandIDs.createLauncher, {
label: trans.__('New Launcher'),
execute: () => Private.createLauncher(commands, browser)
});
commands.addCommand(CommandIDs.toggleNavigateToCurrentDirectory, {
label: trans.__('Show Active File in File Browser'),
isToggled: () => browser.navigateToCurrentDirectory,
@ -852,77 +696,6 @@ function addCommands(
});
}
/**
* A menu widget that dynamically populates with different widget factories
* based on current filebrowser selection.
*/
class OpenWithMenu extends Menu {
protected onBeforeAttach(msg: Message): void {
// clear the current menu items
this.clearItems();
// get the widget factories that could be used to open all of the items
// in the current filebrowser selection
const factories = tracker.currentWidget
? OpenWithMenu._intersection(
map(tracker.currentWidget.selectedItems(), i => {
return OpenWithMenu._getFactories(i);
})
)
: undefined;
if (factories) {
// make new menu items from the widget factories
factories.forEach(factory => {
this.addItem({
args: { factory: factory },
command: CommandIDs.open
});
});
}
super.onBeforeAttach(msg);
}
static _getFactories(item: Contents.IModel): Array<string> {
const factories = registry
.preferredWidgetFactories(item.path)
.map(f => f.name);
const notebookFactory = registry.getWidgetFactory('notebook')?.name;
if (
notebookFactory &&
item.type === 'notebook' &&
factories.indexOf(notebookFactory) === -1
) {
factories.unshift(notebookFactory);
}
return factories;
}
static _intersection<T>(iter: IIterator<Array<T>>): Set<T> | void {
// pop the first element of iter
const first = iter.next();
// first will be undefined if iter is empty
if (!first) {
return;
}
// "initialize" the intersection from first
const isect = new Set(first);
// reduce over the remaining elements of iter
return reduce(
iter,
(isect, subarr) => {
// filter out all elements not present in both isect and subarr,
// accumulate result in new set
return new Set(subarr.filter(x => isect.has(x)));
},
isect
);
}
}
// matches anywhere on filebrowser
const selectorContent = '.jp-DirListing-content';
// matches all filebrowser items
@ -962,15 +735,6 @@ function addCommands(
rank: 1
});
const openWith = new OpenWithMenu({ commands });
openWith.title.label = trans.__('Open With');
app.contextMenu.addItem({
type: 'submenu',
submenu: openWith,
selector: selectorNotDir,
rank: 2
});
app.contextMenu.addItem({
command: CommandIDs.openBrowserTab,
selector: selectorNotDir,
@ -1041,27 +805,6 @@ function addCommands(
* A namespace for private module data.
*/
namespace Private {
/**
* Create a launcher for a given filebrowser widget.
*/
export function createLauncher(
commands: CommandRegistry,
browser: FileBrowser
): Promise<MainAreaWidget<Launcher>> {
const { model } = browser;
return commands
.execute('launcher:create', { cwd: model.path })
.then((launcher: MainAreaWidget<Launcher>) => {
model.pathChanged.connect(() => {
if (launcher.content) {
launcher.content.cwd = model.path;
}
}, launcher);
return launcher;
});
}
/**
* Get browser object given file path.
*/

@ -0,0 +1,24 @@
.jp-FileBrowser {
height: 100%;
}
.lm-TabPanel {
height: 100%;
}
.jp-TreePanel .lm-TabPanel-tabBar {
border: none;
overflow: visible;
min-height: 28px;
}
.jp-TreePanel .lm-TabBar-tab {
color: var(--jp-ui-font-color0);
font-size: var(--jp-ui-font-size1);
padding: 5px;
}
.jp-TreePanel .lm-TabBar-tabLabel {
padding-left: 5px;
padding-right: 5px;
}

@ -1806,22 +1806,6 @@
"@lumino/widgets" "^1.16.1"
react "^17.0.1"
"@jupyterlab/launcher@^3.0.0-rc.13":
version "3.0.0-rc.13"
resolved "https://registry.yarnpkg.com/@jupyterlab/launcher/-/launcher-3.0.0-rc.13.tgz#f128c1bbb0d23b44ed38a9ff08c4f7f6e8b4b2fd"
integrity sha512-Rh0tELQhHcxEUtsDPaNLA2GLOBFW9U5kXqrGXs8imLyDoxxfgwjugcfab79IltDWX6c6brTHFu6Uei9zaDwdmQ==
dependencies:
"@jupyterlab/apputils" "^3.0.0-rc.13"
"@jupyterlab/translation" "^3.0.0-rc.13"
"@jupyterlab/ui-components" "^3.0.0-rc.13"
"@lumino/algorithm" "^1.3.3"
"@lumino/commands" "^1.12.0"
"@lumino/coreutils" "^1.5.3"
"@lumino/disposable" "^1.4.3"
"@lumino/properties" "^1.2.3"
"@lumino/widgets" "^1.16.1"
react "^17.0.1"
"@jupyterlab/logconsole@^3.0.0-rc.12":
version "3.0.0-rc.12"
resolved "https://registry.yarnpkg.com/@jupyterlab/logconsole/-/logconsole-3.0.0-rc.12.tgz#cb3b9e48577542bdeeb4221c17218b59909ce5cd"
@ -2164,7 +2148,7 @@
"@lumino/signaling" "^1.4.3"
"@lumino/widgets" "^1.16.1"
"@jupyterlab/running@^3.0.0-rc.12", "@jupyterlab/running@^3.0.0-rc.13":
"@jupyterlab/running@^3.0.0-rc.13":
version "3.0.0-rc.13"
resolved "https://registry.yarnpkg.com/@jupyterlab/running/-/running-3.0.0-rc.13.tgz#df0d732d23d6c0c56a1512bfb0a988b05a8af4df"
integrity sha512-852VZ6+H3xSl6DtPBe5VE1NhVprY6xgL9a5EAxeqrTljeC2IbBgt9FjBjYDfBcBkj9kdupuyU8biHbFJKNlSiw==

Loading…
Cancel
Save