Skip to content

Commit 97bc03b

Browse files
committed
Add the restorer
1 parent 79ad725 commit 97bc03b

File tree

4 files changed

+310
-26
lines changed

4 files changed

+310
-26
lines changed

packages/application-extension/src/index.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33

44
import {
55
ILabStatus,
6+
ILayoutRestorer,
67
IRouter,
78
ITreePathUpdater,
89
JupyterFrontEnd,
910
JupyterFrontEndPlugin,
1011
JupyterLab,
12+
LayoutRestorer,
1113
} from '@jupyterlab/application';
1214

1315
import {
@@ -16,7 +18,9 @@ import {
1618
ISanitizer,
1719
ISplashScreen,
1820
IToolbarWidgetRegistry,
21+
IWindowResolver,
1922
showErrorMessage,
23+
WindowResolver,
2024
} from '@jupyterlab/apputils';
2125

2226
import { ConsolePanel } from '@jupyterlab/console';
@@ -40,6 +44,8 @@ import {
4044

4145
import { ISettingRegistry } from '@jupyterlab/settingregistry';
4246

47+
import { IStateDB } from '@jupyterlab/statedb';
48+
4349
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
4450

4551
import {
@@ -176,6 +182,46 @@ const info: JupyterFrontEndPlugin<JupyterLab.IInfo> = {
176182
},
177183
};
178184

185+
/**
186+
* The default layout restorer provider.
187+
*/
188+
const layoutRestorer: JupyterFrontEndPlugin<ILayoutRestorer | null> = {
189+
id: '@jupyter-notebook/application-extension:layout',
190+
description: 'Provides the shell layout restorer.',
191+
requires: [IStateDB],
192+
optional: [INotebookShell],
193+
activate: async (
194+
app: JupyterFrontEnd,
195+
state: IStateDB,
196+
notebookShell: INotebookShell | null
197+
) => {
198+
if (!notebookShell) {
199+
console.log('No layout for this view');
200+
return null;
201+
}
202+
203+
const first = app.started;
204+
const registry = app.commands;
205+
206+
const restorer = new LayoutRestorer({
207+
connector: state,
208+
first,
209+
registry,
210+
});
211+
212+
// Restore the layout.
213+
void notebookShell.restoreLayout(restorer, {}).then(() => {
214+
notebookShell.layoutModified.connect(() => {
215+
void restorer.save(notebookShell.saveLayout());
216+
});
217+
});
218+
219+
return restorer;
220+
},
221+
autoStart: true,
222+
provides: ILayoutRestorer,
223+
};
224+
179225
/**
180226
* The logo plugin.
181227
*/
@@ -465,6 +511,26 @@ const rendermime: JupyterFrontEndPlugin<IRenderMimeRegistry> = {
465511
},
466512
};
467513

514+
/**
515+
* The default window name resolver provider.
516+
*/
517+
const resolver: JupyterFrontEndPlugin<IWindowResolver> = {
518+
id: '@jupyter-notebook/apputils-extension:resolver',
519+
description: 'Provides the window name resolver.',
520+
autoStart: true,
521+
provides: IWindowResolver,
522+
requires: [JupyterFrontEnd.IPaths, IRouter],
523+
activate: async (
524+
app: JupyterFrontEnd,
525+
paths: JupyterFrontEnd.IPaths,
526+
router: IRouter
527+
) => {
528+
const solver = new WindowResolver();
529+
(solver as any)._name = 'nb-default';
530+
return solver;
531+
},
532+
};
533+
468534
/**
469535
* The default Jupyter Notebook application shell.
470536
*/
@@ -491,7 +557,7 @@ const shell: JupyterFrontEndPlugin<INotebookShell> = {
491557
const customLayout = settings.composite['layout'] as any;
492558

493559
// Restore the layout.
494-
void notebookShell.restoreLayout(customLayout);
560+
void notebookShell.restoreLayoutConf(customLayout);
495561
})
496562
.catch((reason) => {
497563
console.error('Fail to load settings for the layout restorer.');
@@ -1189,6 +1255,7 @@ const zen: JupyterFrontEndPlugin<void> = {
11891255
const plugins: JupyterFrontEndPlugin<any>[] = [
11901256
dirty,
11911257
info,
1258+
layoutRestorer,
11921259
logo,
11931260
menus,
11941261
menuSpacer,
@@ -1197,6 +1264,7 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
11971264
pathOpener,
11981265
paths,
11991266
rendermime,
1267+
resolver,
12001268
shell,
12011269
sidePanelVisibility,
12021270
shortcuts,

packages/application/src/panelhandler.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export class SidePanelHandler extends PanelHandler {
119119
* Whether the panel is visible
120120
*/
121121
get isVisible(): boolean {
122-
return this._panel.isVisible;
122+
return this._currentWidget?.isVisible || false;
123123
}
124124

125125
/**
@@ -150,6 +150,13 @@ export class SidePanelHandler extends PanelHandler {
150150
return this._widgetRemoved;
151151
}
152152

153+
/**
154+
* A signal emitting when the panel closes.
155+
*/
156+
get closed(): ISignal<SidePanelHandler, void> {
157+
return this._closed;
158+
}
159+
153160
/**
154161
* Get the close button element.
155162
*/
@@ -209,6 +216,7 @@ export class SidePanelHandler extends PanelHandler {
209216
collapse(): void {
210217
this._currentWidget?.hide();
211218
this._currentWidget = null;
219+
this._closed.emit();
212220
}
213221

214222
/**
@@ -245,6 +253,28 @@ export class SidePanelHandler extends PanelHandler {
245253
this._refreshVisibility();
246254
}
247255

256+
/**
257+
* Dehydrate the panel layout.
258+
*/
259+
dehydrate(): SidePanel.ISideArea {
260+
return {
261+
visible: this.isVisible,
262+
currentWidget: this.currentWidget,
263+
};
264+
}
265+
266+
/**
267+
* Rehydrate the panel.
268+
*/
269+
rehydrate(data: SidePanel.ISideArea) {
270+
if (data.currentWidget) {
271+
this.activate(data.currentWidget.id);
272+
}
273+
if (data.visible) {
274+
this.show();
275+
}
276+
}
277+
248278
/**
249279
* Find the insertion index for a rank item.
250280
*/
@@ -296,6 +326,7 @@ export class SidePanelHandler extends PanelHandler {
296326
private _closeButton: HTMLButtonElement;
297327
private _widgetAdded: Signal<SidePanelHandler, Widget> = new Signal(this);
298328
private _widgetRemoved: Signal<SidePanelHandler, Widget> = new Signal(this);
329+
private _closed: Signal<SidePanelHandler, void> = new Signal(this);
299330
}
300331

301332
/**
@@ -306,6 +337,21 @@ export namespace SidePanel {
306337
* The areas of the sidebar panel
307338
*/
308339
export type Area = 'left' | 'right';
340+
341+
/**
342+
* The restorable description of a sidebar in the user interface.
343+
*/
344+
export interface ISideArea {
345+
/**
346+
* The current widget that has side area focus.
347+
*/
348+
readonly currentWidget: Widget | null;
349+
350+
/**
351+
* A flag denoting whether the side tab bar is visible.
352+
*/
353+
readonly visible: boolean;
354+
}
309355
}
310356

311357
/**

0 commit comments

Comments
 (0)