Skip to content

Commit 1475851

Browse files
authored
Fix toggling the side panels from menu (jupyter#7799)
* Revert "Fix toggle functionality for widgets. (jupyter#7178)" This reverts commit 728807f. * Override menu items to toggle TOC panel and debugger panel * lint * update snapshots
1 parent b8be130 commit 1475851

8 files changed

Lines changed: 236 additions & 15 deletions

File tree

packages/application/src/panelhandler.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -165,20 +165,17 @@ export class SidePanelHandler extends PanelHandler {
165165
* if there is no most recently used.
166166
*/
167167
expand(id?: string): void {
168+
if (this._currentWidget) {
169+
this.collapse();
170+
}
168171
if (id) {
169-
if (this._currentWidget && this._currentWidget.id === id) {
170-
this.collapse();
171-
this.hide();
172-
} else {
173-
this.collapse();
174-
this.hide();
175-
this.activate(id);
176-
this.show();
172+
this.activate(id);
173+
} else {
174+
const visibleWidget = this.currentWidget;
175+
if (visibleWidget) {
176+
this._currentWidget = visibleWidget;
177+
this.activate(visibleWidget.id);
177178
}
178-
} else if (this.currentWidget) {
179-
this._currentWidget = this.currentWidget;
180-
this.activate(this._currentWidget.id);
181-
this.show();
182179
}
183180
}
184181

packages/application/src/shell.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,69 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
379379
}
380380
}
381381

382+
/**
383+
* Return a boolean whether the side panel is visible.
384+
*/
385+
isSidePanelVisible(area: string): boolean {
386+
if (area === 'left') {
387+
return this._leftHandler.isVisible;
388+
} else if (area === 'right') {
389+
return this._rightHandler.isVisible;
390+
}
391+
return false;
392+
}
393+
394+
/**
395+
* Get the area of a widget, given its id.
396+
*
397+
* @param id - the widget id
398+
* @returns the area where the widget belongs, or null.
399+
*/
400+
getWidgetArea(id: string): string | null {
401+
for (const area of ['main', 'top', 'left', 'right', 'menu', 'down']) {
402+
const widget = find(
403+
this.widgets(area as INotebookShell.Area),
404+
(w) => w.id === id
405+
);
406+
if (widget) {
407+
return area;
408+
}
409+
}
410+
return null;
411+
}
412+
413+
/**
414+
* Expand an area.
415+
*/
416+
expand(area: string): void {
417+
if (!['top', 'left', 'right'].includes(area)) {
418+
return;
419+
}
420+
if (area === 'top') {
421+
this.expandTop();
422+
} else if (area === 'left') {
423+
this.expandLeft();
424+
} else if (area === 'right') {
425+
this.expandRight();
426+
}
427+
}
428+
429+
/**
430+
* Collapse an area.
431+
*/
432+
collapse(area: string): void {
433+
if (!['top', 'left', 'right'].includes(area)) {
434+
return;
435+
}
436+
if (area === 'top') {
437+
this.collapseTop();
438+
} else if (area === 'left') {
439+
this.collapseLeft();
440+
} else if (area === 'right') {
441+
this.collapseRight();
442+
}
443+
}
444+
382445
/**
383446
* Collapse the top area and the spacer to make the view more compact.
384447
*/

packages/notebook-extension/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@
4242
"@jupyterlab/application": "~4.6.0-alpha.0",
4343
"@jupyterlab/apputils": "~4.7.0-alpha.0",
4444
"@jupyterlab/cells": "~4.6.0-alpha.0",
45+
"@jupyterlab/debugger": "~4.6.0-alpha.0",
4546
"@jupyterlab/docmanager": "~4.6.0-alpha.0",
4647
"@jupyterlab/notebook": "~4.6.0-alpha.0",
4748
"@jupyterlab/settingregistry": "~4.6.0-alpha.0",
49+
"@jupyterlab/toc": "~6.6.0-alpha.0",
4850
"@jupyterlab/translation": "~4.6.0-alpha.0",
51+
"@lumino/algorithm": "2.0.4",
4952
"@lumino/polling": "^2.1.5",
5053
"@lumino/widgets": "^2.7.2",
5154
"react": "^18.2.0",
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"title": "Menu override",
3+
"description": "Override some menu items",
4+
"jupyter.lab.menus": {
5+
"main": [
6+
{
7+
"id": "jp-mainmenu-view",
8+
"items": [
9+
{
10+
"command": "toc:show-panel",
11+
"disabled": true
12+
},
13+
{
14+
"command": "toc:toggle-panel",
15+
"rank": 4
16+
},
17+
{
18+
"command": "debugger:show-panel",
19+
"disabled": true
20+
},
21+
{
22+
"command": "debugger:toggle-panel",
23+
"rank": 5
24+
}
25+
]
26+
}
27+
]
28+
},
29+
"properties": {},
30+
"additionalProperties": false,
31+
"type": "object"
32+
}

packages/notebook-extension/src/index.ts

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { Cell, CodeCell } from '@jupyterlab/cells';
1717

1818
import { PageConfig, Text, Time, URLExt } from '@jupyterlab/coreutils';
1919

20+
import { IDebugger, IDebuggerSidebar } from '@jupyterlab/debugger';
21+
2022
import { IDocumentManager } from '@jupyterlab/docmanager';
2123

2224
import { DocumentRegistry } from '@jupyterlab/docregistry';
@@ -31,10 +33,14 @@ import {
3133

3234
import { ISettingRegistry } from '@jupyterlab/settingregistry';
3335

36+
import { ITableOfContentsTracker } from '@jupyterlab/toc';
37+
3438
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
3539

3640
import { INotebookShell } from '@jupyter-notebook/application';
3741

42+
import { find } from '@lumino/algorithm';
43+
3844
import { Poll } from '@lumino/polling';
3945

4046
import { Widget } from '@lumino/widgets';
@@ -749,6 +755,122 @@ const editNotebookMetadata: JupyterFrontEndPlugin<void> = {
749755
},
750756
};
751757

758+
/**
759+
* A plugin to replace the menu item activating the TOC panel, to allow toggling it.
760+
*/
761+
const overrideMenuItems: JupyterFrontEndPlugin<void> = {
762+
id: '@jupyter-notebook/notebook-extension:menu-override',
763+
description: 'A plugin to override some menu items',
764+
autoStart: true,
765+
optional: [
766+
IDebuggerSidebar,
767+
IMainMenu,
768+
INotebookShell,
769+
ITableOfContentsTracker,
770+
ITranslator,
771+
],
772+
activate: (
773+
app: JupyterFrontEnd,
774+
debuggerSidebar: IDebugger.ISidebar | null,
775+
mainMenu: IMainMenu | null,
776+
shell: INotebookShell | null,
777+
tocTracker: ITableOfContentsTracker | null,
778+
translator: ITranslator | null
779+
) => {
780+
if (!mainMenu || !shell) {
781+
return;
782+
}
783+
const trans = (translator ?? nullTranslator).load('notebook');
784+
const { commands } = app;
785+
786+
if (tocTracker) {
787+
const TOC_PANEL_ID = 'table-of-contents';
788+
commands.addCommand('toc:toggle-panel', {
789+
label: trans.__('Table of Contents'),
790+
isToggleable: true,
791+
isToggled: () => {
792+
const area = shell.getWidgetArea(TOC_PANEL_ID);
793+
if (!area) {
794+
return false;
795+
}
796+
const widget = find(
797+
shell.widgets(area as INotebookShell.Area),
798+
(w) => w.id === TOC_PANEL_ID
799+
);
800+
if (!widget) {
801+
return false;
802+
}
803+
return shell.isSidePanelVisible(area) && widget.isVisible;
804+
},
805+
execute: () => {
806+
const area = shell.getWidgetArea(TOC_PANEL_ID);
807+
if (!area) {
808+
return;
809+
}
810+
const widget = find(
811+
shell.widgets(area as INotebookShell.Area),
812+
(w) => w.id === TOC_PANEL_ID
813+
);
814+
if (shell.isSidePanelVisible(area) && widget?.isVisible) {
815+
shell.collapse(area);
816+
} else {
817+
shell.activateById(TOC_PANEL_ID);
818+
}
819+
},
820+
describedBy: {
821+
args: {
822+
type: 'object',
823+
properties: {},
824+
},
825+
},
826+
});
827+
}
828+
829+
if (debuggerSidebar) {
830+
const DEBUGGER_PANEL_ID = 'jp-debugger-sidebar';
831+
commands.addCommand('debugger:toggle-panel', {
832+
label: trans.__('Debugger Panel'),
833+
isToggleable: true,
834+
isToggled: () => {
835+
const area = shell.getWidgetArea(DEBUGGER_PANEL_ID);
836+
if (!area) {
837+
return false;
838+
}
839+
const widget = find(
840+
shell.widgets(area as INotebookShell.Area),
841+
(w) => w.id === DEBUGGER_PANEL_ID
842+
);
843+
if (!widget) {
844+
return false;
845+
}
846+
return shell.isSidePanelVisible(area) && widget.isVisible;
847+
},
848+
execute: () => {
849+
const area = shell.getWidgetArea(DEBUGGER_PANEL_ID);
850+
if (!area) {
851+
return;
852+
}
853+
const widget = find(
854+
shell.widgets(area as INotebookShell.Area),
855+
(w) => w.id === DEBUGGER_PANEL_ID
856+
);
857+
if (shell.isSidePanelVisible(area) && widget?.isVisible) {
858+
shell.collapse(area);
859+
} else {
860+
shell.activateById(DEBUGGER_PANEL_ID);
861+
}
862+
},
863+
describedBy: {
864+
args: {
865+
type: 'object',
866+
properties: {},
867+
},
868+
},
869+
});
870+
}
871+
},
872+
};
873+
752874
/**
753875
* Export the plugins as default.
754876
*/
@@ -761,6 +883,7 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
761883
kernelLogo,
762884
kernelStatus,
763885
notebookToolsWidget,
886+
overrideMenuItems,
764887
scrollOutput,
765888
tabIcon,
766889
trusted,
18.2 KB
Loading
29.4 KB
Loading

yarn.lock

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,10 +2485,13 @@ __metadata:
24852485
"@jupyterlab/application": ~4.6.0-alpha.0
24862486
"@jupyterlab/apputils": ~4.7.0-alpha.0
24872487
"@jupyterlab/cells": ~4.6.0-alpha.0
2488+
"@jupyterlab/debugger": ~4.6.0-alpha.0
24882489
"@jupyterlab/docmanager": ~4.6.0-alpha.0
24892490
"@jupyterlab/notebook": ~4.6.0-alpha.0
24902491
"@jupyterlab/settingregistry": ~4.6.0-alpha.0
2492+
"@jupyterlab/toc": ~6.6.0-alpha.0
24912493
"@jupyterlab/translation": ~4.6.0-alpha.0
2494+
"@lumino/algorithm": 2.0.4
24922495
"@lumino/polling": ^2.1.5
24932496
"@lumino/widgets": ^2.7.2
24942497
react: ^18.2.0
@@ -3203,7 +3206,7 @@ __metadata:
32033206
languageName: node
32043207
linkType: hard
32053208

3206-
"@jupyterlab/debugger@npm:^4.6.0-alpha.0":
3209+
"@jupyterlab/debugger@npm:^4.6.0-alpha.0, @jupyterlab/debugger@npm:~4.6.0-alpha.0":
32073210
version: 4.6.0-alpha.0
32083211
resolution: "@jupyterlab/debugger@npm:4.6.0-alpha.0"
32093212
dependencies:
@@ -4466,7 +4469,7 @@ __metadata:
44664469
languageName: node
44674470
linkType: hard
44684471

4469-
"@jupyterlab/toc@npm:^6.6.0-alpha.0":
4472+
"@jupyterlab/toc@npm:^6.6.0-alpha.0, @jupyterlab/toc@npm:~6.6.0-alpha.0":
44704473
version: 6.6.0-alpha.0
44714474
resolution: "@jupyterlab/toc@npm:6.6.0-alpha.0"
44724475
dependencies:
@@ -4880,7 +4883,7 @@ __metadata:
48804883
languageName: node
48814884
linkType: hard
48824885

4883-
"@lumino/algorithm@npm:^2.0.4":
4886+
"@lumino/algorithm@npm:2.0.4, @lumino/algorithm@npm:^2.0.4":
48844887
version: 2.0.4
48854888
resolution: "@lumino/algorithm@npm:2.0.4"
48864889
checksum: ec1532fc294666fb483dd35082ec50ad979d0e9e1daf7a951ca045fd36a1ae88c7c73bf09c1aafed1ea826319f038ec2ed7058f58d214d5ed9f6a4cf61f232e8

0 commit comments

Comments
 (0)