@jupyter-notebook/application-extension 7.0.0-alpha.5 → 7.0.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Jupyter Development Team.
2
2
  // Distributed under the terms of the Modified BSD License.
3
- import { ILabStatus, IRouter, ITreePathUpdater, JupyterFrontEnd, Router } from '@jupyterlab/application';
3
+ import { ILabStatus, IRouter, ITreePathUpdater, JupyterFrontEnd } from '@jupyterlab/application';
4
4
  import { sessionContextDialogs, ISessionContextDialogs, DOMUtils, ICommandPalette, IToolbarWidgetRegistry } from '@jupyterlab/apputils';
5
5
  import { ConsolePanel } from '@jupyterlab/console';
6
6
  import { PageConfig, PathExt, URLExt } from '@jupyterlab/coreutils';
@@ -13,7 +13,8 @@ import { NotebookApp, NotebookShell, INotebookShell } from '@jupyter-notebook/ap
13
13
  import { jupyterIcon } from '@jupyter-notebook/ui-components';
14
14
  import { PromiseDelegate } from '@lumino/coreutils';
15
15
  import { DisposableDelegate, DisposableSet } from '@lumino/disposable';
16
- import { Widget } from '@lumino/widgets';
16
+ import { Menu, Widget } from '@lumino/widgets';
17
+ import { SideBarPalette } from './sidebarpalette';
17
18
  /**
18
19
  * A regular expression to match path to notebooks and documents
19
20
  */
@@ -31,6 +32,10 @@ var CommandIDs;
31
32
  * Toggle Top Bar visibility
32
33
  */
33
34
  CommandIDs.toggleTop = 'application:toggle-top';
35
+ /**
36
+ * Toggle sidebar visibility
37
+ */
38
+ CommandIDs.togglePanel = 'application:toggle-panel';
34
39
  /**
35
40
  * Toggle the Zen mode
36
41
  */
@@ -90,7 +95,8 @@ const logo = {
90
95
  elementPosition: 'center',
91
96
  padding: '2px 2px 2px 8px',
92
97
  height: '28px',
93
- width: 'auto'
98
+ width: 'auto',
99
+ cursor: 'pointer'
94
100
  });
95
101
  logo.id = 'jp-NotebookLogo';
96
102
  app.shell.add(logo, 'top', { rank: 0 });
@@ -118,7 +124,7 @@ const opener = {
118
124
  const file = decodeURIComponent(path);
119
125
  const urlParams = new URLSearchParams(parsed.search);
120
126
  const factory = (_b = urlParams.get('factory')) !== null && _b !== void 0 ? _b : 'default';
121
- app.restored.then(async () => {
127
+ app.started.then(async () => {
122
128
  docManager.open(file, factory, undefined, {
123
129
  ref: '_noref'
124
130
  });
@@ -130,8 +136,6 @@ const opener = {
130
136
  };
131
137
  /**
132
138
  * A plugin to customize menus
133
- *
134
- * TODO: use this plugin to customize the menu items and their order
135
139
  */
136
140
  const menus = {
137
141
  id: '@jupyter-notebook/application-extension:menus',
@@ -215,29 +219,6 @@ const paths = {
215
219
  return app.paths;
216
220
  }
217
221
  };
218
- /**
219
- * The default URL router provider.
220
- */
221
- const router = {
222
- id: '@jupyter-notebook/application-extension:router',
223
- autoStart: true,
224
- provides: IRouter,
225
- requires: [JupyterFrontEnd.IPaths],
226
- activate: (app, paths) => {
227
- const { commands } = app;
228
- const base = paths.urls.base;
229
- const router = new Router({ base, commands });
230
- void app.started.then(() => {
231
- // Route the very first request on load.
232
- void router.route();
233
- // Route all pop state events.
234
- window.addEventListener('popstate', () => {
235
- void router.route();
236
- });
237
- });
238
- return router;
239
- }
240
- };
241
222
  /**
242
223
  * The default session dialogs plugin
243
224
  */
@@ -351,11 +332,11 @@ const title = {
351
332
  label: () => trans.__('Rename…'),
352
333
  isEnabled,
353
334
  execute: async () => {
354
- var _a, _b;
335
+ var _a;
355
336
  if (!isEnabled()) {
356
337
  return;
357
338
  }
358
- const result = await renameDialog(docManager, current.context.path);
339
+ const result = await renameDialog(docManager, current.context);
359
340
  // activate the current widget to bring the focus
360
341
  if (current) {
361
342
  current.activate();
@@ -363,13 +344,13 @@ const title = {
363
344
  if (result === null) {
364
345
  return;
365
346
  }
366
- const newPath = (_a = current.context.path) !== null && _a !== void 0 ? _a : result.path;
347
+ const newPath = current.context.path;
367
348
  const basename = PathExt.basename(newPath);
368
349
  h.textContent = basename.replace(STRIP_IPYNB, '');
369
350
  if (!router) {
370
351
  return;
371
352
  }
372
- const matches = (_b = router.current.path.match(TREE_PATTERN)) !== null && _b !== void 0 ? _b : [];
353
+ const matches = (_a = router.current.path.match(TREE_PATTERN)) !== null && _a !== void 0 ? _a : [];
373
354
  const [, route, path] = matches;
374
355
  if (!route || !path) {
375
356
  return;
@@ -449,6 +430,190 @@ const topVisibility = {
449
430
  },
450
431
  autoStart: true
451
432
  };
433
+ /**
434
+ * Plugin to toggle the left or right sidebar's visibility.
435
+ */
436
+ const sidebarVisibility = {
437
+ id: '@jupyter-notebook/application-extension:sidebar',
438
+ requires: [INotebookShell, ITranslator],
439
+ optional: [IMainMenu, ICommandPalette],
440
+ autoStart: true,
441
+ activate: (app, notebookShell, translator, menu, palette) => {
442
+ const trans = translator.load('notebook');
443
+ /* Arguments for togglePanel command:
444
+ * side, left or right area
445
+ * title, widget title to show in the menu
446
+ * id, widget ID to activate in the sidebar
447
+ */
448
+ app.commands.addCommand(CommandIDs.togglePanel, {
449
+ label: args => args['title'],
450
+ caption: args => {
451
+ // We do not substitute the parameter into the string because the parameter is not
452
+ // localized (e.g., it is always 'left') even though the string is localized.
453
+ if (args['side'] === 'left') {
454
+ return trans.__('Show %1 in the left sidebar', args['title']);
455
+ }
456
+ else if (args['side'] === 'right') {
457
+ return trans.__('Show %1 in the right sidebar', args['title']);
458
+ }
459
+ return trans.__('Show %1 in the sidebar', args['title']);
460
+ },
461
+ execute: args => {
462
+ var _a, _b;
463
+ switch (args['side']) {
464
+ case 'left':
465
+ if (notebookShell.leftCollapsed) {
466
+ notebookShell.expandLeft(args.id);
467
+ }
468
+ else if (((_a = notebookShell.leftHandler.currentWidget) === null || _a === void 0 ? void 0 : _a.id) !== args.id) {
469
+ notebookShell.expandLeft(args.id);
470
+ }
471
+ else {
472
+ notebookShell.collapseLeft();
473
+ if (notebookShell.currentWidget) {
474
+ notebookShell.activateById(notebookShell.currentWidget.id);
475
+ }
476
+ }
477
+ break;
478
+ case 'right':
479
+ if (notebookShell.rightCollapsed) {
480
+ notebookShell.expandRight(args.id);
481
+ }
482
+ else if (((_b = notebookShell.rightHandler.currentWidget) === null || _b === void 0 ? void 0 : _b.id) !== args.id) {
483
+ notebookShell.expandRight(args.id);
484
+ }
485
+ else {
486
+ notebookShell.collapseRight();
487
+ if (notebookShell.currentWidget) {
488
+ notebookShell.activateById(notebookShell.currentWidget.id);
489
+ }
490
+ }
491
+ break;
492
+ }
493
+ },
494
+ isToggled: args => {
495
+ switch (args['side']) {
496
+ case 'left': {
497
+ if (notebookShell.leftCollapsed) {
498
+ return false;
499
+ }
500
+ const currentWidget = notebookShell.leftHandler.currentWidget;
501
+ if (!currentWidget) {
502
+ return false;
503
+ }
504
+ return currentWidget.id === args['id'];
505
+ }
506
+ case 'right': {
507
+ if (notebookShell.rightCollapsed) {
508
+ return false;
509
+ }
510
+ const currentWidget = notebookShell.rightHandler.currentWidget;
511
+ if (!currentWidget) {
512
+ return false;
513
+ }
514
+ return currentWidget.id === args['id'];
515
+ }
516
+ }
517
+ return false;
518
+ }
519
+ });
520
+ const sideBarMenu = {
521
+ left: null,
522
+ right: null
523
+ };
524
+ /**
525
+ * The function which adds entries to the View menu for each widget of a sidebar.
526
+ *
527
+ * @param area - 'left' or 'right', the area of the side bar.
528
+ * @param entryLabel - the name of the main entry in the View menu for that sidebar.
529
+ * @returns - The disposable menu added to the View menu or null.
530
+ */
531
+ const updateMenu = (area, entryLabel) => {
532
+ var _a;
533
+ if (menu === null) {
534
+ return null;
535
+ }
536
+ // Remove the previous menu entry for this sidebar.
537
+ (_a = sideBarMenu[area]) === null || _a === void 0 ? void 0 : _a.dispose();
538
+ // Creates a new menu entry and populates it with sidebar widgets.
539
+ const newMenu = new Menu({ commands: app.commands });
540
+ newMenu.title.label = entryLabel;
541
+ const widgets = notebookShell.widgets(area);
542
+ let menuToAdd = false;
543
+ for (let widget of widgets) {
544
+ newMenu.addItem({
545
+ command: CommandIDs.togglePanel,
546
+ args: {
547
+ side: area,
548
+ title: `Show ${widget.title.caption}`,
549
+ id: widget.id
550
+ }
551
+ });
552
+ menuToAdd = true;
553
+ }
554
+ // If there are widgets, add the menu to the main menu entry.
555
+ if (menuToAdd) {
556
+ sideBarMenu[area] = menu.viewMenu.addItem({
557
+ type: 'submenu',
558
+ submenu: newMenu
559
+ });
560
+ }
561
+ };
562
+ app.restored.then(() => {
563
+ // Create menu entries for the left and right panel.
564
+ if (menu) {
565
+ const getSideBarLabel = (area) => {
566
+ if (area === 'left') {
567
+ return trans.__(`Left Sidebar`);
568
+ }
569
+ else {
570
+ return trans.__(`Right Sidebar`);
571
+ }
572
+ };
573
+ const leftArea = notebookShell.leftHandler.area;
574
+ const leftLabel = getSideBarLabel(leftArea);
575
+ updateMenu(leftArea, leftLabel);
576
+ const rightArea = notebookShell.rightHandler.area;
577
+ const rightLabel = getSideBarLabel(rightArea);
578
+ updateMenu(rightArea, rightLabel);
579
+ const handleSideBarChange = (sidebar, widget) => {
580
+ const label = getSideBarLabel(sidebar.area);
581
+ updateMenu(sidebar.area, label);
582
+ };
583
+ notebookShell.leftHandler.widgetAdded.connect(handleSideBarChange);
584
+ notebookShell.leftHandler.widgetRemoved.connect(handleSideBarChange);
585
+ notebookShell.rightHandler.widgetAdded.connect(handleSideBarChange);
586
+ notebookShell.rightHandler.widgetRemoved.connect(handleSideBarChange);
587
+ }
588
+ // Add palette entries for side panels.
589
+ if (palette) {
590
+ const sideBarPalette = new SideBarPalette({
591
+ commandPalette: palette,
592
+ command: CommandIDs.togglePanel
593
+ });
594
+ notebookShell.leftHandler.widgets.forEach(widget => {
595
+ sideBarPalette.addItem(widget, notebookShell.leftHandler.area);
596
+ });
597
+ notebookShell.rightHandler.widgets.forEach(widget => {
598
+ sideBarPalette.addItem(widget, notebookShell.rightHandler.area);
599
+ });
600
+ // Update menu and palette when widgets are added or removed from sidebars.
601
+ notebookShell.leftHandler.widgetAdded.connect((sidebar, widget) => {
602
+ sideBarPalette.addItem(widget, sidebar.area);
603
+ });
604
+ notebookShell.leftHandler.widgetRemoved.connect((sidebar, widget) => {
605
+ sideBarPalette.removeItem(widget, sidebar.area);
606
+ });
607
+ notebookShell.rightHandler.widgetAdded.connect((sidebar, widget) => {
608
+ sideBarPalette.addItem(widget, sidebar.area);
609
+ });
610
+ notebookShell.rightHandler.widgetRemoved.connect((sidebar, widget) => {
611
+ sideBarPalette.removeItem(widget, sidebar.area);
612
+ });
613
+ }
614
+ });
615
+ }
616
+ };
452
617
  /**
453
618
  * The default tree route resolver plugin.
454
619
  */
@@ -568,9 +733,9 @@ const plugins = [
568
733
  opener,
569
734
  pages,
570
735
  paths,
571
- router,
572
736
  sessionDialogs,
573
737
  shell,
738
+ sidebarVisibility,
574
739
  status,
575
740
  tabTitle,
576
741
  title,
@@ -0,0 +1,61 @@
1
+ import { ICommandPalette } from '@jupyterlab/apputils';
2
+ import { IDisposable } from '@lumino/disposable';
3
+ import { Widget } from '@lumino/widgets';
4
+ /**
5
+ * A class to manages the palette entries associated to the side bar.
6
+ */
7
+ export declare class SideBarPalette {
8
+ /**
9
+ * Construct a new side bar palette.
10
+ */
11
+ constructor(options: SideBarPaletteOption);
12
+ /**
13
+ * Get a command palette item from the widget id and the area.
14
+ */
15
+ getItem(widget: Readonly<Widget>, area: 'left' | 'right'): SideBarPaletteItem | null;
16
+ /**
17
+ * Add an item to the command palette.
18
+ */
19
+ addItem(widget: Readonly<Widget>, area: 'left' | 'right'): void;
20
+ /**
21
+ * Remove an item from the command palette.
22
+ */
23
+ removeItem(widget: Readonly<Widget>, area: 'left' | 'right'): void;
24
+ _command: string;
25
+ _commandPalette: ICommandPalette;
26
+ _items: SideBarPaletteItem[];
27
+ }
28
+ declare type SideBarPaletteItem = {
29
+ /**
30
+ * The ID of the widget associated to the command palette.
31
+ */
32
+ widgetId: string;
33
+ /**
34
+ * The area of the panel associated to the command palette.
35
+ */
36
+ area: 'left' | 'right';
37
+ /**
38
+ * The disposable object to remove the item from command palette.
39
+ */
40
+ disposable: IDisposable;
41
+ };
42
+ /**
43
+ * An interface for the options to include in SideBarPalette constructor.
44
+ */
45
+ declare type SideBarPaletteOption = {
46
+ /**
47
+ * The commands palette.
48
+ */
49
+ commandPalette: ICommandPalette;
50
+ /**
51
+ * The command to call from each sidebar menu entry.
52
+ *
53
+ * ### Notes
54
+ * That command required 3 args :
55
+ * side: 'left' | 'right', the area to toggle
56
+ * title: string, label of the command
57
+ * id: string, id of the widget to activate
58
+ */
59
+ command: string;
60
+ };
61
+ export {};
@@ -0,0 +1,61 @@
1
+ /**
2
+ * A class to manages the palette entries associated to the side bar.
3
+ */
4
+ export class SideBarPalette {
5
+ /**
6
+ * Construct a new side bar palette.
7
+ */
8
+ constructor(options) {
9
+ this._items = [];
10
+ this._commandPalette = options.commandPalette;
11
+ this._command = options.command;
12
+ }
13
+ /**
14
+ * Get a command palette item from the widget id and the area.
15
+ */
16
+ getItem(widget, area) {
17
+ const itemList = this._items;
18
+ for (let i = 0; i < itemList.length; i++) {
19
+ const item = itemList[i];
20
+ if (item.widgetId == widget.id && item.area == area) {
21
+ return item;
22
+ }
23
+ }
24
+ return null;
25
+ }
26
+ /**
27
+ * Add an item to the command palette.
28
+ */
29
+ addItem(widget, area) {
30
+ // Check if the item does not already exist.
31
+ if (this.getItem(widget, area)) {
32
+ return;
33
+ }
34
+ // Add a new item in command palette.
35
+ const disposableDelegate = this._commandPalette.addItem({
36
+ command: this._command,
37
+ category: 'View',
38
+ args: {
39
+ side: area,
40
+ title: `Show ${widget.title.caption}`,
41
+ id: widget.id
42
+ }
43
+ });
44
+ // Keep the disposableDelegate objet to be able to dispose of the item if the widget
45
+ // is remove from the side bar.
46
+ this._items.push({
47
+ widgetId: widget.id,
48
+ area: area,
49
+ disposable: disposableDelegate
50
+ });
51
+ }
52
+ /**
53
+ * Remove an item from the command palette.
54
+ */
55
+ removeItem(widget, area) {
56
+ const item = this.getItem(widget, area);
57
+ if (item) {
58
+ item.disposable.dispose();
59
+ }
60
+ }
61
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter-notebook/application-extension",
3
- "version": "7.0.0-alpha.5",
3
+ "version": "7.0.0-alpha.7",
4
4
  "description": "Jupyter Notebook - Application Extension",
5
5
  "homepage": "https://github.com/jupyter/notebook",
6
6
  "bugs": {
@@ -39,27 +39,26 @@
39
39
  "watch": "tsc -b --watch"
40
40
  },
41
41
  "dependencies": {
42
- "@jupyter-notebook/application": "^7.0.0-alpha.5",
43
- "@jupyter-notebook/ui-components": "^7.0.0-alpha.5",
44
- "@jupyterlab/application": "^4.0.0-alpha.10",
45
- "@jupyterlab/apputils": "^4.0.0-alpha.10",
46
- "@jupyterlab/celltags": "^4.0.0-alpha.10",
47
- "@jupyterlab/codeeditor": "^4.0.0-alpha.10",
48
- "@jupyterlab/codemirror": "^4.0.0-alpha.10",
49
- "@jupyterlab/console": "^4.0.0-alpha.10",
50
- "@jupyterlab/coreutils": "^6.0.0-alpha.10",
51
- "@jupyterlab/docmanager": "^4.0.0-alpha.10",
52
- "@jupyterlab/docregistry": "^4.0.0-alpha.10",
53
- "@jupyterlab/mainmenu": "^4.0.0-alpha.10",
54
- "@jupyterlab/settingregistry": "^4.0.0-alpha.10",
55
- "@jupyterlab/translation": "^4.0.0-alpha.10",
56
- "@lumino/coreutils": "^1.12.0",
57
- "@lumino/disposable": "^1.10.1",
58
- "@lumino/widgets": "^1.32.0"
42
+ "@jupyter-notebook/application": "^7.0.0-alpha.7",
43
+ "@jupyter-notebook/ui-components": "^7.0.0-alpha.7",
44
+ "@jupyterlab/application": "^4.0.0-alpha.15",
45
+ "@jupyterlab/apputils": "^4.0.0-alpha.15",
46
+ "@jupyterlab/celltags": "^4.0.0-alpha.15",
47
+ "@jupyterlab/codeeditor": "^4.0.0-alpha.15",
48
+ "@jupyterlab/console": "^4.0.0-alpha.15",
49
+ "@jupyterlab/coreutils": "^6.0.0-alpha.15",
50
+ "@jupyterlab/docmanager": "^4.0.0-alpha.15",
51
+ "@jupyterlab/docregistry": "^4.0.0-alpha.15",
52
+ "@jupyterlab/mainmenu": "^4.0.0-alpha.15",
53
+ "@jupyterlab/settingregistry": "^4.0.0-alpha.15",
54
+ "@jupyterlab/translation": "^4.0.0-alpha.15",
55
+ "@lumino/coreutils": "^2.0.0-alpha.6",
56
+ "@lumino/disposable": "^2.0.0-alpha.6",
57
+ "@lumino/widgets": "^2.0.0-alpha.6"
59
58
  },
60
59
  "devDependencies": {
61
- "rimraf": "~3.0.0",
62
- "typescript": "~4.6.3"
60
+ "rimraf": "^3.0.2",
61
+ "typescript": "~4.7.3"
63
62
  },
64
63
  "publishConfig": {
65
64
  "access": "public"
package/style/base.css CHANGED
@@ -16,3 +16,10 @@
16
16
  .jp-Toolbar > .jp-Toolbar-item {
17
17
  height: unset;
18
18
  }
19
+
20
+ #jp-UserMenu {
21
+ flex: 0 0 auto;
22
+ display: flex;
23
+ text-align: center;
24
+ margin-top: 8px;
25
+ }