向 Jupyterlabs 主菜单添加新菜单

Adding a new menu to the main Jupyterlabs menu

我正在尝试编写一个插件以将新菜单添加到 Jupyterlabs 界面中的现有菜单....与 fileedit、... Settings,以及Help

基本的 xkcd example 运行良好,我已经 运行 绕过 packages/mainmenu 中的代码,尝试使用 tab 菜单作为示例(我' ll 也许 稍后添加上下文选项和内容...)

这是我所在的位置:

    import { PageConfig } from '@jupyterlab/coreutils';
    import { JupyterLab, JupyterLabPlugin } from '@jupyterlab/application';
    import { IMainMenu, IJupyterLabMenu, JupyterLabMenu } from '@jupyterlab/mainmenu';
    import { Menu } from '@phosphor/widgets';

    interface INoteableMenu extends IJupyterLabMenu {}

    class NoteableMenu extends JupyterLabMenu implements INoteableMenu {
      constructor(options: Menu.IOptions) {
        super(options);
        this.menu.title.label = 'Noteable';
      }
    }

    const extension: JupyterLabPlugin<void> = {
      id: 'noteable-menu',
      autoStart: true,
      activate: (app: JupyterLab) => {
        console.log('JupyterLab extension noteable is activated!');
        let mainMenu: IMainMenu;  //app.contextMenu??
        //let noteableMenu = new NoteableMenu({ commands: {} });
        mainMenu.addMenu(NoteableMenu.menu, { rank: 2000 });
      }
    };

    export default extension;

    export namespace CommandIDs {
      export const returnToHome = 'noteablemenu:home';
      export const switchToClassic = 'noteablemenu:classic';
    }

    export function createNoteableMenu(
      menu: NoteableMenu,
    ): void {
      const commands = menu.menu.commands;

      commands.addCommand(CommandIDs.returnToHome, {
        label: 'Jump to example page',
        execute: () => {
          location.assign(location.origin + '/example');
        }
      });

      commands.addCommand(CommandIDs.switchToClassic, {
        label: 'Switch to Classic Notebook',
        execute: () => {
          location.assign(PageConfig.getBaseUrl() + 'tree');
        }
      });
    }

构建失败(使用 jupyter labextension install . --no-build 错误

src/index.ts:26:35 - error TS2339: Property 'menu' does not exist on type 'typeof NoteableMenu'.
26     mainMenu.addMenu(NoteableMenu.menu, { rank: 2000 });
                                     ~~~~

我无法弄清楚我的代码与源示例在实用性上有何不同。

提示、线索甚至直截了当的答案表示赞赏...

(供参考:nodejs: v8.10.0jupyterlab: 0.35.5

这是完整的 index.ts 文件:

import { IMainMenu } from '@jupyterlab/mainmenu';
import { JupyterLab, JupyterLabPlugin } from '@jupyterlab/application';
import { Menu } from '@phosphor/widgets';
import { Token } from '@phosphor/coreutils';
import { PageConfig } from '@jupyterlab/coreutils';

export const EXTENSION_ID = 'jupyter.extensions.noteable_plugin';

/** Interface for extension class */
export interface INoteableExtension {}

// tslint:disable-next-line: variable-name
export const INoteableExtension = new Token<INoteableExtension>(EXTENSION_ID);

export class NoteableExtension implements INoteableExtension {
  // private app: JupyterLab;
  constructor( app: JupyterLab ) {}
  //{ this.app = app; }
}

/**
 * The command IDs used by the help plugin.
 */
export namespace CommandIDs {
  export const returnUI = 'noteable:returnUI';
  export const switchClassic = 'noteable:launch-classic-notebook';
}

/**
 * The default running sessions extension.
 */
const plugin: JupyterLabPlugin<INoteableExtension> = {
  id: 'jupyter.extensions.running-sessions-Noteable',
  requires: [
    IMainMenu,
  ],
  provides: INoteableExtension,
  activate,
  autoStart: true
};


/**
 * Export the plugin as default.
 */
export default plugin;

function activate(
  app: JupyterLab,
  mainMenu: IMainMenu,
): INoteableExtension {
  const { commands } = app;
  let noteableExtension = new NoteableExtension(app);
  const category = 'Noteable';

  // Rank has been chosen somewhat arbitrarily to give priority to the running
  // sessions widget in the sidebar.
  addCommands(app);
  let menu = new Menu({ commands });

  menu.title.label = category;
  [CommandIDs.returnUI, CommandIDs.switchClassic].forEach(
    command => {
      menu.addItem({ command });
    }
  );

  mainMenu.addMenu(menu, { rank: 60 });

  return noteableExtension;
}

/**
 * Add the commands for the git extension.
 */
export function addCommands(app: JupyterLab) {
  let { commands } = app;

  commands.addCommand(CommandIDs.returnUI, {
    label: 'Return to JupyterHub Home',
    execute: () => {
      location.assign(location.origin + '/home');
    }
  });

  commands.addCommand(CommandIDs.switchClassic, {
    label: 'Switch to Classic Notebook',
    execute: () => {
      location.assign(PageConfig.getBaseUrl() + 'tree');
    }
  });

}