diff --git a/packages/lab-extension/package.json b/packages/lab-extension/package.json index b2d0043c..21b79387 100644 --- a/packages/lab-extension/package.json +++ b/packages/lab-extension/package.json @@ -50,8 +50,11 @@ "@jupyterlab/docregistry": "^3.1.8", "@jupyterlab/mainmenu": "^3.1.8", "@jupyterlab/notebook": "^3.1.8", + "@jupyterlab/translation": "^3.1.8", + "@jupyterlab/ui-components": "^3.1.8", "@lumino/commands": "^1.15.0", "@lumino/disposable": "^1.7.0", + "@retrolab/application": "^0.3.3", "@retrolab/ui-components": "^0.3.3" }, "devDependencies": { diff --git a/packages/lab-extension/src/index.ts b/packages/lab-extension/src/index.ts index 5d5cf53f..189f6f40 100644 --- a/packages/lab-extension/src/index.ts +++ b/packages/lab-extension/src/index.ts @@ -7,91 +7,86 @@ import { JupyterFrontEndPlugin } from '@jupyterlab/application'; -import { ICommandPalette, ToolbarButton } from '@jupyterlab/apputils'; +import { CommandToolbarButton, ICommandPalette } from '@jupyterlab/apputils'; import { PageConfig } from '@jupyterlab/coreutils'; -import { DocumentRegistry } from '@jupyterlab/docregistry'; - import { IMainMenu } from '@jupyterlab/mainmenu'; +import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook'; + import { ITranslator } from '@jupyterlab/translation'; import { - INotebookModel, - INotebookTracker, - NotebookPanel -} from '@jupyterlab/notebook'; - -import { retroSunIcon } from '@retrolab/ui-components'; + jupyterIcon, + jupyterFaviconIcon, + LabIcon +} from '@jupyterlab/ui-components'; -import { CommandRegistry } from '@lumino/commands'; +import { IRetroShell } from '@retrolab/application'; -import { IDisposable } from '@lumino/disposable'; +import { retroSunIcon } from '@retrolab/ui-components'; /** * The command IDs used by the application plugin. */ namespace CommandIDs { /** - * Toggle Top Bar visibility + * Launch RetroLab Tree */ - export const openRetro = 'retrolab:open'; - export const launchRetroTree = 'retrolab:launchtree'; -} + export const launchRetroTree = 'retrolab:launch-tree'; -/** - * A notebook widget extension that adds a retrolab button to the toolbar. - */ -class RetroButton - implements DocumentRegistry.IWidgetExtension { /** - * Instantiate a new RetroButton. - * @param commands The command registry. + * Open RetroLab */ - constructor(commands: CommandRegistry) { - this._commands = commands; - } + export const openRetro = 'retrolab:open-retro'; /** - * Create a new extension object. + * Open in Classic Notebook */ - createNew(panel: NotebookPanel): IDisposable { - const button = new ToolbarButton({ - tooltip: 'Open with RetroLab', - icon: retroSunIcon, - onClick: () => { - this._commands.execute(CommandIDs.openRetro); - } - }); - panel.toolbar.insertAfter('cellType', 'retro', button); - return button; - } + export const openClassic = 'retrolab:open-classic'; - private _commands: CommandRegistry; + /** + * Open in JupyterLab + */ + export const openLab = 'retrolab:open-lab'; +} + +interface ISwitcherChoice { + command: string; + commandLabel: string; + buttonLabel: string; + icon: LabIcon; + urlPrefix: string; } /** - * A plugin for the checkpoint indicator + * A plugin to add custom toolbar items to the notebook page */ -const openRetro: JupyterFrontEndPlugin = { - id: '@retrolab/lab-extension:open-retro', +const launchButtons: JupyterFrontEndPlugin = { + id: '@retrolab/lab-extension:interface-switcher', autoStart: true, - optional: [INotebookTracker, ICommandPalette, IMainMenu, ILabShell], + optional: [ + INotebookTracker, + ICommandPalette, + IMainMenu, + IRetroShell, + ILabShell + ], activate: ( app: JupyterFrontEnd, notebookTracker: INotebookTracker | null, palette: ICommandPalette | null, menu: IMainMenu | null, + retroShell: IRetroShell | null, labShell: ILabShell | null ) => { - // TODO: do not activate if already in a IRetroShell? - if (!notebookTracker || !labShell) { + if (!notebookTracker) { // to prevent showing the toolbar button in RetroLab return; } - const { commands, docRegistry, shell } = app; + const { commands, shell } = app; const baseUrl = PageConfig.getBaseUrl(); const isEnabled = () => { @@ -101,29 +96,75 @@ const openRetro: JupyterFrontEndPlugin = { ); }; - commands.addCommand(CommandIDs.openRetro, { - label: 'Open in RetroLab', - execute: () => { - const current = notebookTracker.currentWidget; - if (!current) { - return; + const addInterface = (option: ISwitcherChoice) => { + const { command, icon, buttonLabel, commandLabel, urlPrefix } = option; + commands.addCommand(command, { + label: args => (args.noLabel ? '' : commandLabel), + caption: commandLabel, + icon, + execute: () => { + const current = notebookTracker.currentWidget; + if (!current) { + return; + } + window.open(`${urlPrefix}${current.context.path}`); + }, + isEnabled + }); + + if (palette) { + palette.addItem({ command, category: 'Other' }); + } + + if (menu) { + menu.viewMenu.addGroup([{ command }], 1); + } + + notebookTracker.widgetAdded.connect( + async (sender: INotebookTracker, panel: NotebookPanel) => { + panel.toolbar.insertBefore( + 'kernelName', + buttonLabel, + new CommandToolbarButton({ + commands, + id: command, + args: { noLabel: 1 } + }) + ); + await panel.context.ready; + commands.notifyCommandChanged(); } - const { context } = current; - window.open(`${baseUrl}retro/notebooks/${context.path}`); - }, - isEnabled + ); + }; + + // always add Classic + addInterface({ + command: 'retrolab:open-classic', + commandLabel: 'Open in Classic Notebook', + buttonLabel: 'openClassic', + icon: jupyterIcon, + urlPrefix: `${baseUrl}tree/` }); - if (palette) { - palette.addItem({ command: CommandIDs.openRetro, category: 'Other' }); + if (!retroShell) { + addInterface({ + command: 'retrolab:open-retro', + commandLabel: 'Open in RetroLab', + buttonLabel: 'openRetro', + icon: retroSunIcon, + urlPrefix: `${baseUrl}retro/tree/` + }); } - if (menu) { - menu.viewMenu.addGroup([{ command: CommandIDs.openRetro }], 1); + if (!labShell) { + addInterface({ + command: 'retrolab:open-lab', + commandLabel: 'Open in JupyterLab', + buttonLabel: 'openLab', + icon: jupyterFaviconIcon, + urlPrefix: `${baseUrl}doc/tree/` + }); } - - const retroButton = new RetroButton(commands); - docRegistry.addWidgetExtension('Notebook', retroButton); } }; @@ -166,6 +207,6 @@ const launchRetroTree: JupyterFrontEndPlugin = { /** * Export the plugins as default. */ -const plugins: JupyterFrontEndPlugin[] = [launchRetroTree, openRetro]; +const plugins: JupyterFrontEndPlugin[] = [launchRetroTree, launchButtons]; export default plugins; diff --git a/packages/lab-extension/tsconfig.json b/packages/lab-extension/tsconfig.json index 1b9e4bfd..34d11b40 100644 --- a/packages/lab-extension/tsconfig.json +++ b/packages/lab-extension/tsconfig.json @@ -6,6 +6,9 @@ }, "include": ["src/**/*"], "references": [ + { + "path": "../application" + }, { "path": "../ui-components" }