Skip to content
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ ui-tests/playwright-report
ui-tests/.yarn/*
ui-tests/.pnp.*

# keep potential upstream patches
!.yarn/patches

# generated html
notebook/templates/*.html

Expand Down
27 changes: 15 additions & 12 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"@jupyterlab/imageviewer-extension": "~4.4.0-rc.1",
"@jupyterlab/javascript-extension": "~4.4.0-rc.1",
"@jupyterlab/json-extension": "~4.4.0-rc.1",
"@jupyterlab/logconsole-extension": "~4.4.0-rc.1",
"@jupyterlab/lsp": "~4.4.0-rc.1",
"@jupyterlab/lsp-extension": "~4.4.0-rc.1",
"@jupyterlab/mainmenu": "~4.4.0-rc.1",
Expand Down Expand Up @@ -107,18 +108,18 @@
"@jupyterlab/vega5-extension": "~4.4.0-rc.1",
"@lezer/common": "~1.2.1",
"@lezer/highlight": "~1.2.0",
"@lumino/algorithm": "~2.0.2",
"@lumino/application": "~2.4.2",
"@lumino/commands": "~2.3.1",
"@lumino/coreutils": "~2.2.0",
"@lumino/disposable": "~2.1.3",
"@lumino/domutils": "~2.0.2",
"@lumino/dragdrop": "~2.1.5",
"@lumino/messaging": "~2.0.2",
"@lumino/properties": "~2.0.2",
"@lumino/signaling": "~2.1.3",
"@lumino/virtualdom": "~2.0.2",
"@lumino/widgets": "~2.6.0",
"@lumino/algorithm": "~2.0.3",
"@lumino/application": "~2.4.3",
"@lumino/commands": "~2.3.2",
"@lumino/coreutils": "~2.2.1",
"@lumino/disposable": "~2.1.4",
"@lumino/domutils": "~2.0.3",
"@lumino/dragdrop": "~2.1.6",
"@lumino/messaging": "~2.0.3",
"@lumino/properties": "~2.0.3",
"@lumino/signaling": "~2.1.4",
"@lumino/virtualdom": "~2.0.3",
"@lumino/widgets": "~2.7.0",
"react": "~18.2.0",
"react-dom": "~18.2.0",
"yjs": "~13.6.8"
Expand Down Expand Up @@ -158,6 +159,7 @@
"@jupyterlab/imageviewer-extension": "~4.4.0-rc.1",
"@jupyterlab/javascript-extension": "~4.4.0-rc.1",
"@jupyterlab/json-extension": "~4.4.0-rc.1",
"@jupyterlab/logconsole-extension": "~4.4.0-rc.1",
"@jupyterlab/lsp": "~4.4.0-rc.1",
"@jupyterlab/lsp-extension": "~4.4.0-rc.1",
"@jupyterlab/mainmenu-extension": "~4.4.0-rc.1",
Expand Down Expand Up @@ -337,6 +339,7 @@
"@jupyterlab/debugger-extension:sidebar",
"@jupyterlab/debugger-extension:sources"
],
"@jupyterlab/logconsole-extension": true,
"@jupyterlab/metadataform-extension": true,
"@jupyterlab/notebook-extension": [
"@jupyterlab/notebook-extension:active-cell-tool",
Expand Down
51 changes: 48 additions & 3 deletions packages/application/src/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import {
FocusTracker,
Panel,
SplitPanel,
TabPanel,
Widget,
} from '@lumino/widgets';
import { PanelHandler, SidePanelHandler } from './panelhandler';
import { TabPanelSvg } from '@jupyterlab/ui-components';

/**
* The Jupyter Notebook application shell token.
Expand All @@ -37,7 +39,7 @@ export namespace INotebookShell {
/**
* The areas of the application shell where widgets can reside.
*/
export type Area = 'main' | 'top' | 'menu' | 'left' | 'right';
export type Area = 'main' | 'top' | 'menu' | 'left' | 'right' | 'down';

/**
* Widget position
Expand Down Expand Up @@ -134,6 +136,18 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
middlePanel.addWidget(this._spacer_bottom);
middlePanel.layout = middleLayout;

const vsplitPanel = new SplitPanel();
vsplitPanel.id = 'jp-main-vsplit-panel';
vsplitPanel.spacing = 1;
vsplitPanel.orientation = 'vertical';
SplitPanel.setStretch(vsplitPanel, 1);

const downPanel = new TabPanelSvg({
tabsMovable: true,
});
this._downPanel = downPanel;
this._downPanel.id = 'jp-down-stack';

// TODO: Consider storing this as an attribute this._hsplitPanel if saving/restoring layout needed
const hsplitPanel = new SplitPanel();
hsplitPanel.id = 'main-split-panel';
Expand All @@ -153,8 +167,21 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
// panel.
hsplitPanel.setRelativeSizes([1, 2.5, 1]);

vsplitPanel.addWidget(hsplitPanel);
vsplitPanel.addWidget(downPanel);

rootLayout.spacing = 0;
rootLayout.addWidget(hsplitPanel);
rootLayout.addWidget(vsplitPanel);

// initially hiding the down panel
this._downPanel.hide();

// Connect down panel change listeners
this._downPanel.tabBar.tabMoved.connect(this._onTabPanelChanged, this);
this._downPanel.stackedPanel.widgetRemoved.connect(
this._onTabPanelChanged,
this
);

this.layout = rootLayout;

Expand Down Expand Up @@ -267,7 +294,7 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
*/
activateById(id: string): void {
// Search all areas that can have widgets for this widget, starting with main.
for (const area of ['main', 'top', 'left', 'right', 'menu']) {
for (const area of ['main', 'top', 'left', 'right', 'menu', 'down']) {
const widget = find(
this.widgets(area as INotebookShell.Area),
(w) => w.id === id
Expand All @@ -277,6 +304,9 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
this.expandLeft(id);
} else if (area === 'right') {
this.expandRight(id);
} else if (area === 'down') {
this._downPanel.show();
widget.activate();
} else {
widget.activate();
}
Expand Down Expand Up @@ -342,6 +372,8 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
return this._leftHandler.addWidget(widget, rank);
case 'right':
return this._rightHandler.addWidget(widget, rank);
case 'down':
return this._downPanel.addWidget(widget);
default:
console.warn(`Cannot add widget to area: ${area}`);
}
Expand Down Expand Up @@ -385,6 +417,9 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
case 'right':
yield* this._rightHandler.widgets;
return;
case 'down':
yield* this._downPanel.widgets;
return;
default:
console.error(`This shell has no area called "${area}"`);
return;
Expand Down Expand Up @@ -432,6 +467,15 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
this._userLayout = configuration;
}

/**
* Handle a change on the down panel widgets
*/
private _onTabPanelChanged(): void {
if (this._downPanel.stackedPanel.widgets.length === 0) {
this._downPanel.hide();
}
}

private _topWrapper: Panel;
private _topHandler: PanelHandler;
private _menuWrapper: Panel;
Expand All @@ -442,6 +486,7 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
private _spacer_bottom: Widget;
private _skipLinkWidgetHandler: Private.SkipLinkWidgetHandler;
private _main: Panel;
private _downPanel: TabPanel;
private _translator: ITranslator = nullTranslator;
private _currentChanged = new Signal<this, FocusTracker.IChangedArgs<Widget>>(
this
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions ui-tests/test/notebook.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Jupyter Development Team.

Check failure on line 1 in ui-tests/test/notebook.spec.ts

View workflow job for this annotation

GitHub Actions / ui-tests (chromium)

[chromium] › test/notebook.spec.ts:24:7 › Notebook › Title should be rendered

1) [chromium] › test/notebook.spec.ts:24:7 › Notebook › Title should be rendered ───────────────── Error: "apiRequestContext.fetch: Target page, context or browser has been closed Call log: - → POST http://localhost:8888/api/sessions?1743618291479 - user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/134.0.6998.35 Safari/537.36 - accept: */* - accept-encoding: gzip,deflate,br - accept-language: en-US - content-type: text/plain;charset=UTF-8 - cookie: username-localhost-8888=2|1:0|10:1743618289|23:username-localhost-8888|188:eyJ1c2VybmFtZSI6ICJiYjMyMWIxZjAzNWM0MzllYjlkMzEyNjk1NWFjOTRjOSIsICJuYW1lIjogIkFub255bW91cyBFcnNhIiwgImRpc3BsYXlfbmFtZSI6ICJBbm9ueW1vdXMgRXJzYSIsICJpbml0aWFscyI6ICJBRSIsICJjb2xvciI6IG51bGx9|43e3aa00b08b1faa6bb294ec58d8fa54300195c9fa098097066a7cd5d89cc853; _xsrf=2|4318cee1|f73bd33ceda9d4b4c6adf6b88a4e553f|1743618289 - origin: http://localhost:8888 - referer: http://localhost:8888/notebooks/test-notebook-Notebook-Title-should-be-rendered-chromium/example.ipynb - x-xsrftoken: 2|4318cee1|f73bd33ceda9d4b4c6adf6b88a4e553f|1743618289 - sec-ch-ua: "Chromium";v="134", "Not:A-Brand";v="24", "HeadlessChrome";v="134" - sec-ch-ua-mobile: ?0 - sec-ch-ua-platform: "Linux" - content-length: 173 " while running route callback. Consider awaiting `await page.unrouteAll({ behavior: 'ignoreErrors' })` before the end of the test to ignore remaining routes in flight. at /home/runner/work/notebook/notebook/ui-tests/node_modules/@jupyterlab/galata/src/galata.ts:961:49
// Distributed under the terms of the Modified BSD License.

import path from 'path';
Expand Down Expand Up @@ -206,4 +206,21 @@
await page.menu.clickMenuItem(menuPath);
await expect(notebookPanel).not.toHaveClass(/jp-mod-fullwidth/);
});

test('Open the log console widget in the down area', async ({
page,
tmpPath,
}) => {
const notebook = 'simple.ipynb';
await page.contents.uploadFile(
path.resolve(__dirname, `./notebooks/${notebook}`),
`${tmpPath}/${notebook}`
);
await page.goto(`notebooks/${tmpPath}/${notebook}`);

const menuPath = 'View>Show Log Console';
await page.menu.clickMenuItem(menuPath);

await expect(page.locator('.jp-LogConsole')).toBeVisible();
});
});
23 changes: 23 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2167,6 +2167,7 @@ __metadata:
"@jupyterlab/imageviewer-extension": ~4.4.0-rc.1
"@jupyterlab/javascript-extension": ~4.4.0-rc.1
"@jupyterlab/json-extension": ~4.4.0-rc.1
"@jupyterlab/logconsole-extension": ~4.4.0-rc.1
"@jupyterlab/lsp": ~4.4.0-rc.1
"@jupyterlab/lsp-extension": ~4.4.0-rc.1
"@jupyterlab/mainmenu-extension": ~4.4.0-rc.1
Expand Down Expand Up @@ -3832,6 +3833,28 @@ __metadata:
languageName: node
linkType: hard

"@jupyterlab/logconsole-extension@npm:~4.4.0-rc.1":
version: 4.4.0-rc.1
resolution: "@jupyterlab/logconsole-extension@npm:4.4.0-rc.1"
dependencies:
"@jupyterlab/application": ^4.4.0-rc.1
"@jupyterlab/apputils": ^4.5.0-rc.1
"@jupyterlab/coreutils": ^6.4.0-rc.1
"@jupyterlab/docregistry": ^4.4.0-rc.1
"@jupyterlab/logconsole": ^4.4.0-rc.1
"@jupyterlab/rendermime": ^4.4.0-rc.1
"@jupyterlab/settingregistry": ^4.4.0-rc.1
"@jupyterlab/statusbar": ^4.4.0-rc.1
"@jupyterlab/translation": ^4.4.0-rc.1
"@jupyterlab/ui-components": ^4.4.0-rc.1
"@lumino/coreutils": ^2.2.1
"@lumino/signaling": ^2.1.4
"@lumino/widgets": ^2.7.0
react: ^18.2.0
checksum: b49a7a16162dd612f8e7acb24d505cfaa4540957c82630c53392e5d93be8333795777c5a31cd3a5c3864f89cff0ba725980832a86778baf952a65eacf2659a14
languageName: node
linkType: hard

"@jupyterlab/logconsole@npm:^4.4.0-rc.1":
version: 4.4.0-rc.1
resolution: "@jupyterlab/logconsole@npm:4.4.0-rc.1"
Expand Down
Loading