@jupyterlab/application#JupyterFrontEnd TypeScript Examples

The following examples show how to use @jupyterlab/application#JupyterFrontEnd. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From jupyterlab-tabular-data-editor with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Builds a context menu for specific portion of the datagrid
 * @param app The JupyterFrontEnd which contains the context menu
 * @param commands An array of commands, use 'separator' for dividers (see CommandIDs dictionary in index.ts)
 * @param selector The current portion of the datagrid BODY_SELECTOR | COLUMN_HEADER_SELECTOR | ROW_HEADER_SELECTOR
 */
function buildContextMenu(
  app: JupyterFrontEnd,
  commands: Array<string>,
  selector: string
): void {
  // iterate over every command adding it to the context menu
  commands.forEach((command: string): void => {
    // if the command is a separator, add a separator
    command === 'separator'
      ? app.contextMenu.addItem({
          type: 'separator',
          selector: selector
        })
      : app.contextMenu.addItem({
          command: CommandIDs[command],
          selector: selector
        });
  });
}
Example #2
Source File: index.ts    From stickyland with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
plugin = {
  id: 'jupyterlab_stickyland',
  autoStart: true,
  requires: [ICommandPalette],
  activate: function (app: JupyterFrontEnd) {
    console.log('Activating StickyLand.');
    app.docRegistry.addWidgetExtension('Notebook', new ButtonExtension());
  }
}
Example #3
Source File: jupyterlab-plugin.ts    From beakerx_tabledisplay with Apache License 2.0 6 votes vote down vote up
plugin: JupyterFrontEndPlugin<void> = {
  id: 'beakerx_tabledisplay:plugin',
  requires: [IJupyterWidgetRegistry],
  optional: [IThemeManager],
  autoStart: true,
  activate: (app: JupyterFrontEnd, widgets: IJupyterWidgetRegistry, themeManager: IThemeManager | null): void => {
    class TableDisplayView extends beakerx_tabledisplay.TableDisplayView {
      constructor(options?: WidgetView.InitializeParameters) {
        super(options);
        
        if (themeManager) {
          themeManager.themeChanged.connect(this._onThemeChanged, this);
        }
      }
    
      protected _onThemeChanged(): void {
        // Recompute CSS variables and redraw
        this.currentScope.computeCSSVariablesAndRedraw();
      }
    
      public remove(): void {
        if (themeManager) {
          themeManager.themeChanged.disconnect(this._onThemeChanged, this);
        }
        return super.remove();
      }
    }

    widgets.registerWidget({
      name: 'beakerx_tabledisplay',
      version: BEAKERX_MODULE_VERSION,
      exports: {
        TableDisplayModel: beakerx_tabledisplay.TableDisplayModel,
        TableDisplayView
      }
    });
    
  }
}
Example #4
Source File: plugin.tsx    From jupyterlab-tour with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
function activateDefaults(
  app: JupyterFrontEnd,
  tourManager: ITourManager,
  nbTracker?: INotebookTracker
): void {
  addTours(tourManager, app, nbTracker);

  if (nbTracker) {
    nbTracker.widgetAdded.connect(() => {
      if (tourManager.tours.has(NOTEBOOK_ID)) {
        tourManager.launch([NOTEBOOK_ID], false);
      }
    });
  }

  app.restored.then(() => {
    if (tourManager.tours.has(WELCOME_ID)) {
      // Wait 3s before launching the first tour - to be sure element are loaded
      setTimeout(() => tourManager.launch([WELCOME_ID], false), 3000);
    }
  });
}
Example #5
Source File: plugin.tsx    From jupyterlab-tour with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
function activateUser(
  app: JupyterFrontEnd,
  settings: ISettingRegistry,
  tourManager: ITourManager,
  translator?: ITranslator
): IUserTourManager {
  translator = translator || nullTranslator;

  const manager = new UserTourManager({
    tourManager,
    translator,
    getSettings: (): Promise<ISettingRegistry.ISettings> =>
      settings.load(USER_PLUGIN_ID)
  });
  return manager;
}
Example #6
Source File: defaults.tsx    From jupyterlab-tour with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Add all default tours
 *
 * @param manager Tours manager
 * @param app Jupyter application
 * @param nbTracker Notebook tracker (optional)
 */
export function addTours(
  manager: ITourManager,
  app: JupyterFrontEnd,
  nbTracker?: INotebookTracker
): void {
  const { commands, shell } = app;
  addWelcomeTour(manager, commands);
  addNotebookTour(manager, commands, shell as ILabShell, nbTracker);
}
Example #7
Source File: plugin.ts    From jupyter-videochat with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
function activateToggleArea(
  app: JupyterFrontEnd,
  chat: IVideoChatManager,
  palette?: ICommandPalette
): void {
  const { shell, commands } = app;
  const { __ } = chat;

  const labShell = isFullLab(app) ? (shell as LabShell) : null;

  if (!labShell) {
    return;
  }

  const toggleBtn = new CommandToolbarButton({
    id: CommandIds.toggleArea,
    commands,
    icon: launcherIcon,
  });

  chat.mainWidget
    .then((widget) => {
      widget.toolbar.insertBefore(
        ToolbarIds.SPACER_LEFT,
        ToolbarIds.TOGGLE_AREA,
        toggleBtn
      );
    })
    .catch((err) => console.warn(__(`Couldn't add Video Chat area toggle`), err));

  if (palette) {
    palette.addItem({ command: CommandIds.toggleArea, category: __(category) });
  }
}
Example #8
Source File: index.ts    From jupyterlab-execute-time with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
extension: JupyterFrontEndPlugin<void> = {
  id: PLUGIN_NAME,
  autoStart: true,
  requires: [INotebookTracker, ISettingRegistry],
  activate: (
    app: JupyterFrontEnd,
    tracker: INotebookTracker,
    settingRegistry: ISettingRegistry
  ) => {
    app.docRegistry.addWidgetExtension(
      'Notebook',
      new ExecuteTimeWidgetExtension(tracker, settingRegistry)
    );

    // eslint-disable-next-line no-console
    console.log('JupyterLab extension jupyterlab-execute-time is activated!');
  },
}
Example #9
Source File: index.ts    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
menu: JupyterFrontEndPlugin<void> = {
  id: 'jupyterlab-ros/menu',
  autoStart: true,
  requires: [IMainMenu],
  optional: [],
  activate: (app: JupyterFrontEnd, mainMenu: IMainMenu) => {
    
    const { commands } = app;

    // Create a new menu
    const menu: Menu = new Menu({ commands });
    menu.title.label = 'ROS';
    mainMenu.addMenu(menu, { rank: 80 });
    
    // Open Zethus
    menu.addItem({ command: 'jupyterlab-ros/zethus:open' });
    menu.addItem({ type: 'separator' });

    // Open Logger
    menu.addItem({ command: 'jupyterlab-ros/logConsole:open' });
    menu.addItem({ type: 'separator' });

    // Open Settings
    menu.addItem({ command: 'jupyterlab-ros/settings:open' });
  }
}
Example #10
Source File: index.ts    From jupyter-extensions with Apache License 2.0 6 votes vote down vote up
async function activate(
  app: JupyterFrontEnd,
  shell: ILabShell,
  manager: IDocumentManager
) {
  const service = new GitSyncService(shell, manager);
  const widget = new GitSyncWidget(service);
  app.shell.add(widget, 'left', { rank: 100 });
}
Example #11
Source File: logConsoleWidget.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
constructor(app: JupyterFrontEnd) {
    super({ content: new LogConsolePanel() });
    this.addClass('jp-logConsole');
    this.id = 'jupyterlab-ros/logConsole:widget';
    this.title.closable = true;
    this.title.label = 'ROS Log console';
    this.title.icon = listIcon;

    const server = ServerConnection.makeSettings();
    this.url = URLExt.join(server.wsUrl, 'ros/bridge');
    this.ros = new ROSLIB.Ros({ url: this.url });
    this.ros.on('connection', this.onConection);
    this.ros.on('error', this.onError);
    this.ros.on('close', this.onClose);
    this.listener = new ROSLIB.Topic({
      ros: this.ros,
      name: '/rosout',
      messageType: 'rosgraph_msgs/Log'
    });
    
    this.listener.subscribe(this.onMessage);

    this.status = new LogStatus(this.ros, this.url);
    this.levelSwitcher = new LogLevelSwitcher(this.content);
    this.nodeSwicher = new LogNodeSwitcher(this.content);
    this.logs = [];

    // Adding the buttons in widget toolbar
    this.toolbar.addItem('status', this.status);
    this.toolbar.addItem('checkpoint',
      new CommandToolbarButton({commands: app.commands, id: 'jupyterlab-ros/logConsole:checkpoint'})
    );
    this.toolbar.addItem('clear', 
      new CommandToolbarButton({commands: app.commands, id: 'jupyterlab-ros/logConsole:clear'})
    );
    this.toolbar.addItem('level', this.levelSwitcher);
    this.toolbar.addItem('topic', this.nodeSwicher);
  }
Example #12
Source File: index.ts    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
master: JupyterFrontEndPlugin<void> = {
  id: 'jupyterlab-ros/master',
  autoStart: true,
  requires: [IStatusBar],
  optional: [],
  activate: (app: JupyterFrontEnd, statusBar: IStatusBar) => {
    
    if (!statusBar) { console.log("No status bar!"); return; }
    
    statusBar.registerStatusItem('jupyterlab-ros/master:status', {
      item: new StatusMaster(),
      align: 'left',
      rank: 4,
      isActive: () => true
    });
  }
}
Example #13
Source File: plugin.ts    From jupyter-videochat with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Create the server room plugin
 *
 * In the future, this might `provide` itself with some reasonable API,
 * but is already accessible from the manager, which is likely preferable.
 */
function activateServerRooms(
  app: JupyterFrontEnd,
  chat: IVideoChatManager,
  router?: IRouter
): void {
  const { __ } = chat;

  const { commands } = app;
  const provider = new ServerRoomProvider({
    serverSettings: app.serviceManager.serverSettings,
  });

  chat.registerRoomProvider({
    id: 'server',
    label: __('Server'),
    rank: 0,
    provider,
  });

  // If available, Add to the router
  if (router) {
    commands.addCommand(CommandIds.serverRouterStart, {
      label: 'Open Server Video Chat from URL',
      execute: async (args) => {
        const { request } = args as IRouter.ILocation;
        const url = new URL(`http://example.com${request}`);
        const params = url.searchParams;
        const displayName = params.get(SERVER_URL_PARAM);

        const chatAfterRoute = async () => {
          router.routed.disconnect(chatAfterRoute);
          if (chat.currentRoom?.displayName != displayName) {
            await commands.execute(CommandIds.open, { displayName });
          }
        };

        router.routed.connect(chatAfterRoute);
      },
    });

    router.register({
      command: CommandIds.serverRouterStart,
      pattern: /.*/,
      rank: 29,
    });
  }
}
Example #14
Source File: widget_manager.ts    From jupyter-extensions with Apache License 2.0 5 votes vote down vote up
constructor(private app: JupyterFrontEnd) {}
Example #15
Source File: index.ts    From sparkmonitor with Apache License 2.0 5 votes vote down vote up
extension = {
    id: 'jupyterlab_sparkmonitor',
    autoStart: true,
    requires: [INotebookTracker, IMainMenu],
    activate(app: JupyterFrontEnd, notebooks: NotebookTracker, mainMenu: MainMenu) {
        let monitor: SparkMonitor;
        console.log('JupyterLab SparkMonitor is activated!');
        notebooks.widgetAdded.connect(async (sender, nbPanel) => {
            let notebookStore = store.notebooks[nbPanel.id];
            if (!notebookStore) {
                notebookStore = new NotebookStore(nbPanel.id);
                store.notebooks[nbPanel.id] = notebookStore;
            }

            // JupyterLab 1.0 backwards compatibility
            let kernel;
            let info;
            if ((nbPanel as any).session) {
                await (nbPanel as any).session.ready;
                kernel = (nbPanel as any).session.kernel;
                await kernel.ready;
                info = kernel.info;
            } else {
                // JupyterLab 2.0
                const { sessionContext } = nbPanel;
                await sessionContext.ready;
                kernel = sessionContext.session?.kernel;
                info = await kernel?.info;
            }

            if (info.language_info.name === 'python') {
                monitor = new SparkMonitor(nbPanel, notebookStore);
                console.log('Notebook kernel ready');
                monitor.startComm();
            }
        });

        const commandID = 'toggle-monitor';
        let toggled = false;

        app.commands.addCommand(commandID, {
            label: 'Hide Spark Monitoring',
            isEnabled: () => true,
            isVisible: () => true,
            isToggled: () => toggled,
            execute: () => {
                console.log(`Executed ${commandID}`);
                toggled = !toggled;
                monitor?.toggleAll();
            },
        });

        const menu = new Menu({ commands: app.commands });
        menu.title.label = 'Spark';
        menu.addItem({
            command: commandID,
            args: {},
        });

        mainMenu.addMenu(menu, { rank: 40 });
    },
}
Example #16
Source File: index.ts    From jupyterlab-unfold with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
extension: JupyterFrontEndPlugin<IFileBrowserFactory> = {
  id: EXTENSION_ID,
  provides: IFileBrowserFactory,
  requires: [IDocumentManager, ITranslator, ISettingRegistry],
  optional: [IStateDB],
  activate: async (
    app: JupyterFrontEnd,
    docManager: IDocumentManager,
    translator: ITranslator,
    settings: ISettingRegistry,
    state: IStateDB | null
  ): Promise<IFileBrowserFactory> => {
    const setting = await settings.load(SETTINGS_ID);

    const tracker = new WidgetTracker<FileTreeBrowser>({ namespace });
    const createFileBrowser = (
      id: string,
      options: IFileBrowserFactory.IOptions = {}
    ) => {
      const model = new FilterFileTreeBrowserModel({
        translator: translator,
        auto: options.auto ?? true,
        manager: docManager,
        driveName: options.driveName || '',
        refreshInterval: options.refreshInterval,
        state:
          options.state === null
            ? undefined
            : options.state || state || undefined
      });
      const widget = new FileTreeBrowser({
        id,
        model,
        restore: true,
        translator,
        app
      });

      widget.listing.singleClickToUnfold = setting.get('singleClickToUnfold')
        .composite as boolean;

      setting.changed.connect(() => {
        widget.listing.singleClickToUnfold = setting.get('singleClickToUnfold')
          .composite as boolean;
      });

      // Track the newly created file browser.
      void tracker.add(widget);

      return widget;
    };

    // Manually restore and load the default file browser.
    const defaultBrowser = createFileBrowser(EXTENSION_ID, {
      auto: false,
      restore: false
    });

    // TODO Remove this! Why is this needed?
    // The @jupyterlab/filebrowser-extension:launcher-toolbar-button extension should take care of this
    const { commands } = app;
    const trans = translator.load('jupyterlab');

    // Add a launcher toolbar item.
    const launcher = new ToolbarButton({
      icon: addIcon,
      onClick: () => {
        if (commands.hasCommand('launcher:create')) {
          return commands.execute('launcher:create');
        }
      },
      tooltip: trans.__('New Launcher'),
      actualOnClick: true
    });
    defaultBrowser.toolbar.insertItem(0, 'launch', launcher);

    return { createFileBrowser, defaultBrowser, tracker };
  }
}
Example #17
Source File: index.ts    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
bag: JupyterFrontEndPlugin<void> = {
  id: 'jupyterlab-ros/bag',
  autoStart: true,
  requires: [IFileBrowserFactory, ILayoutRestorer],
  optional: [],
  activate: (app: JupyterFrontEnd, factory: IFileBrowserFactory, restorer: ILayoutRestorer) => {
    
    app.docRegistry.addFileType({
      name: 'bag',
      icon: runIcon,
      displayName: 'Bag File',
      extensions: ['.bag'],
      contentType: 'file',
      fileFormat: 'base64',
      iconClass: runIcon.name,
      iconLabel: runIcon.name,
      mimeTypes: ['application/octet-stream']
    });

    const tracker = new WidgetTracker<BagWidget>({ namespace: 'rosbag' });

    restorer.restore(tracker, {
      command: 'jupyterlab-ros/bag:launch',
      args: widget => ({ path: widget.content.model.session.path }),
      name: widget => widget.content.model.session.name
    });

    app.commands.addCommand('jupyterlab-ros/bag:launch', {
      label: 'Open Bag',
      caption: 'Open ROS bag file.',
      icon: runIcon,
      execute: (args: any) => {
        console.log("launch");

        const path = ( args.path || factory.tracker.currentWidget.selectedItems().next().path );

        app.serviceManager.sessions.findByPath(path)
        .then( model => {

          if (model) {
            const session = app.serviceManager.sessions.connectTo({ model });
            const widget = new BagWidget(new BagPanel(new BagModel(session)));
  
            app.shell.add(widget, 'main');
            tracker.add(widget);
          
          } else {
            const session = new SessionContext({
              sessionManager: app.serviceManager.sessions,
              specsManager: app.serviceManager.kernelspecs,
              name: path,
              path: path
            });
  
            session.initialize()
            .then( async value => {
              if (value) {
                await sessionContextDialogs.selectKernel(session);
                const widget = new BagWidget(new BagPanel(new BagModel(session.session)));
                
                app.shell.add(widget, 'main');
                tracker.add(widget);
              }
            }).catch( err => console.error(err) );
          }
          
        }).catch( err => console.log(err) );
      }
    });

    app.contextMenu.addItem({
      command: 'jupyterlab-ros/bag:launch',
      selector: '.jp-DirListing-item[data-file-type="bag"]',
      rank: 0
    });
  }
}
Example #18
Source File: plugin.tsx    From jupyterlab-tour with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
function activate(
  app: JupyterFrontEnd,
  stateDB: IStateDB,
  palette?: ICommandPalette,
  menu?: MainMenu,
  translator?: ITranslator
): ITourManager {
  const { commands } = app;

  translator = translator ?? nullTranslator;

  // Create tour manager
  const manager = new TourManager(stateDB, translator, menu);

  commands.addCommand(CommandIDs.launch, {
    label: args => {
      if (args['id']) {
        const tour = manager.tours.get(args['id'] as string) as TourHandler;
        return manager.translator.__(tour.label);
      } else {
        return manager.translator.__('Launch a Tour');
      }
    },
    usage: manager.translator.__(
      'Launch a tour.\nIf no id provided, prompt the user.\nArguments {id: Tour ID}'
    ),
    isEnabled: () => !manager.activeTour,
    execute: async args => {
      let id = args['id'] as string;
      const force =
        args['force'] === undefined ? true : (args['force'] as boolean);

      if (!id) {
        const answer = await InputDialog.getItem({
          items: Array.from(manager.tours.keys()),
          title: manager.translator.__('Choose a tour')
        });

        if (answer.button.accept && answer.value) {
          id = answer.value;
        } else {
          return;
        }
      }

      manager.launch([id], force);
    }
  });

  commands.addCommand(CommandIDs.addTour, {
    label: manager.translator.__('Add a tour'),
    usage: manager.translator.__(
      'Add a tour and returns it.\nArguments {tour: ITour}\nReturns `null` if a failure occurs.'
    ),
    execute: (args): ITourHandler | null => {
      return manager.addTour(args.tour as any);
    }
  });

  if (palette) {
    palette.addItem({
      category: manager.translator.__('Help'),
      command: CommandIDs.launch
    });
  }

  const node = document.createElement('div');

  document.body.appendChild(node);
  ReactDOM.render(<TourContainer tourLaunched={manager.tourLaunched} />, node);

  return manager;
}
Example #19
Source File: index.ts    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
launch: JupyterFrontEndPlugin<void> = {
  id: 'jupyterlab-ros/launch',
  autoStart: true,
  requires: [IFileBrowserFactory, IStatusBar],
  optional: [],
  activate: (app: JupyterFrontEnd, factory: IFileBrowserFactory, statusBar: IStatusBar) => {
    let status: StatusLaunch = null;
    
    app.docRegistry.addFileType({
      name: 'launch',
      icon: launcherIcon,
      displayName: 'Launch File',
      extensions: ['.launch'],
      fileFormat: 'text',
      contentType: 'file',
      mimeTypes: ['application/xml']
    });

    app.commands.addCommand('jupyterlab-ros/launch:launch', {
      label: 'Launch',
      caption: 'Launch ROS launch file.',
      icon: launcherIcon,
      isVisible: () => true,
      isEnabled: () => true,
      execute: () => {
        const file = factory.tracker.currentWidget.selectedItems().next();
        status?.launch(file.path);
      }
    });

    app.contextMenu.addItem({
      command: 'jupyterlab-ros/launch:launch',
      selector: '.jp-DirListing-item[data-file-type="launch"]',
      rank: 0
    });

    if (!statusBar) { console.log("No status bar!"); return; }
    status = new StatusLaunch();

    const item = statusBar.registerStatusItem('jupyterlab-ros/launch:status', {
      item: status,
      align: 'left',
      rank: 4,
      isActive: () => true
    });
  }
}
Example #20
Source File: plugin.spec.ts    From jupyterlab-tour with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
function mockApp(): Partial<JupyterFrontEnd> {
  return {
    commands: new CommandRegistry(),
    restored: Promise.resolve()
  };
}
Example #21
Source File: index.ts    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
logConsole: JupyterFrontEndPlugin<void> = {
  id: 'jupyterlab-ros/logConsole',
  autoStart: true,
  requires: [ICommandPalette, ILayoutRestorer],
  optional: [],
  activate: (app: JupyterFrontEnd, palette: ICommandPalette, restorer: ILayoutRestorer) => {
    const { commands } = app;

    let widget: LogConsoleWidget = null;

    const tracker = new WidgetTracker<LogConsoleWidget>({
      namespace: 'roslogconsole'
    });

    restorer.restore(tracker, {
      command: 'jupyterlab-ros/logConsole:open',
      name: () => 'roslogconsole'
    });

    // Creating some buttons for the widget toolbar
    commands.addCommand('jupyterlab-ros/logConsole:checkpoint', {
      execute: () => widget?.checkpoint(),
      icon: addIcon,
      label: 'Add Checkpoint'
    });

    commands.addCommand('jupyterlab-ros/logConsole:clear', {
      execute: () =>  widget?.clear(),
      icon: clearIcon,
      label: 'Clear Log'
    });

    commands.addCommand('jupyterlab-ros/logConsole:open', {
      label: 'Ros log',
      caption: 'Log console for ROS.',
      isVisible: () => true,
      isEnabled: () => true,
      isToggled: () => widget !== null,
      execute: () => {
        if (widget) {
          widget.dispose();
        } else {
          widget = new LogConsoleWidget(app);

          widget.disposed.connect(() => {
            widget = null;
            commands.notifyCommandChanged();
          });

          app.shell.add(widget, 'main', { mode: 'split-bottom' });
          tracker.add(widget);

          widget.update();
          commands.notifyCommandChanged();
        }
      }
    });

    palette.addItem({ command: 'jupyterlab-ros/logConsole:open', category: 'ROS' });
  }
}
Example #22
Source File: plugin.ts    From jupyter-videochat with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
function activateRetro(
  app: JupyterFrontEnd,
  chat: IVideoChatManager,
  filebrowser?: IFileBrowserFactory,
  mainmenu?: IMainMenu
): void {
  if (!PageConfig.getOption(RETRO_CANARY_OPT)) {
    return;
  }

  const { __ } = chat;

  const baseUrl = PageConfig.getBaseUrl();

  // this is basically hard-coded upstream
  const treeUrl = URLExt.join(baseUrl, RETRO_TREE_URL);

  const { commands } = app;

  commands.addCommand(CommandIds.openTab, {
    label: __('New Video Chat'),
    icon: prettyChatIcon,
    execute: (args: any) => {
      window.open(`${treeUrl}?${FORCE_URL_PARAM}`, '_blank');
    },
  });

  // If available, add menu item
  if (mainmenu) {
    mainmenu.fileMenu.newMenu.addGroup([{ command: CommandIds.openTab }]);
  }

  // If available, add button to file browser
  if (filebrowser) {
    const spacer = Toolbar.createSpacerItem();
    spacer.node.style.flex = '1';
    filebrowser.defaultBrowser.toolbar.insertItem(999, 'videochat-spacer', spacer);
    filebrowser.defaultBrowser.toolbar.insertItem(
      1000,
      'new-videochat',
      new CommandToolbarButton({
        commands,
        id: CommandIds.openTab,
      })
    );
  }
}
Example #23
Source File: plugin.ts    From jupyter-videochat with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
function isFullLab(app: JupyterFrontEnd) {
  return !!(app.shell as ILabShell).layoutModified;
}
Example #24
Source File: index.ts    From jupyter-extensions with Apache License 2.0 5 votes vote down vote up
function activate(
  app: JupyterFrontEnd,
  labShell: ILabShell,
  palette: ICommandPalette,
  docManager: IDocumentManager
) {
  console.log('JupyterLab extension jupyterlab_comments is activated!');

  let widget: MainAreaWidget<CommentsWidget>;
  let content: CommentsWidget;

  const context = {
    labShell: labShell,
    docManager: docManager,
  };

  // Add an application command
  const command = 'comments:open';
  app.commands.addCommand(command, {
    label: 'Notebook comments in git',
    execute: () => {
      if (!widget || widget.isDisposed) {
        content = new CommentsWidget(context);
        widget = new MainAreaWidget<CommentsWidget>({ content });
        widget.id = 'jupyterlab_comments';
        widget.title.label = 'Comments';
        widget.title.closable = true;
      }

      if (!widget.isAttached) {
        app.shell.add(widget, 'right', { rank: 200 });
      }
      app.shell.activateById(widget.id);
    },
  });
  // Add the command to the palette.
  palette.addItem({ command, category: 'Collaboration' });

  /*
  Command for adding new comment to currently selected line in the file
  This command only support non-Notebook files
  */
  const addNewComment = 'comments:add';
  app.commands.addCommand(addNewComment, {
    execute: () => {
      const file = (labShell.currentWidget as IDocumentWidget)
        .content as FileEditor;
      if (!widget) {
        return;
      }
      const selectionObj = file.editor.getSelection(); //contains start and end line and column attributes
      const dialogWidget = new NewCommentDialogWidget(selectionObj, context);
      dialogWidget.id = 'new_comment';

      app.shell.add(dialogWidget, 'bottom'); //attach widget to UI to display dialog
      app.shell.activateById(dialogWidget.id);
    },
    label: 'New comment',
  });
  //Add command to file editor's right click context menu
  app.contextMenu.addItem({
    command: addNewComment,
    selector: '.jp-FileEditor',
    rank: 1,
  });
}
Example #25
Source File: index.ts    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
zethus: JupyterFrontEndPlugin<void> = {
  id: "jupyterlab-ros/zethus",
  autoStart: true,
  requires: [ICommandPalette, ILayoutRestorer],
  activate: (app: JupyterFrontEnd, palette: ICommandPalette, restorer: ILayoutRestorer) => {
    const { commands } = app;
    let widget = null;

    const tracker = new WidgetTracker<ZethusWidget>({
      namespace: 'zethus'
    });

    restorer.restore(tracker, {
      command: 'jupyterlab-ros/zethus:open',
      name: () => 'zethus'
    });

    let command = 'jupyterlab-ros/zethus:open';
    commands.addCommand(command, {
      label: 'Open Zethus',
      caption: 'Open a new Zethus view.',
      isVisible: () => true,
      isEnabled: () => true,
      isToggled: () => widget !== null,
      execute: () => {
        if (widget) {
          widget.dispose();
        } else {
          widget = new ZethusWidget();

          widget.disposed.connect(() => {
            widget = null;
            commands.notifyCommandChanged();
          });

          app.shell.add(widget, 'main');
          tracker.add(widget);

          widget.update();
          commands.notifyCommandChanged();
        }
      }
    });

    palette.addItem({ command, category: 'ROS' });
  }
}
Example #26
Source File: index.ts    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
settings: JupyterFrontEndPlugin<void> = {
  id: 'jupyterlab-ros/settings',
  autoStart: true,
  requires: [ICommandPalette, ILayoutRestorer, ISettingRegistry],
  optional: [],
  activate: (app: JupyterFrontEnd, palette: ICommandPalette, restorer: ILayoutRestorer, settings: ISettingRegistry) => {
    const { commands } = app;
    const server = ServerConnection.makeSettings();
    const url = URLExt.join(server.baseUrl, 'ros/setting');

    let content: SettingsWidget = null;
    let widget: MainAreaWidget<SettingsWidget> = null;

    const tracker = new WidgetTracker<MainAreaWidget<SettingsWidget>>({
      namespace: 'rossettings'
    });

    restorer.restore(tracker, {
      command: 'jupyterlab-ros/settings:open',
      name: () => 'rossettings'
    });

    const command = 'jupyterlab-ros/settings:open';
    commands.addCommand(command, {
      label: 'Settings',
      caption: 'Specify your JupyterLab-ROS env.',
      isVisible: () => true,
      isEnabled: () => true,
      isToggled: () => widget !== null,
      execute: () => {
        if (widget) {
          widget.dispose();
        } else {
          content = new SettingsWidget(settings, '@robostack/jupyterlab-ros:settings');
          widget = new MainAreaWidget<SettingsWidget>({ content });
          widget.title.label = 'ROS Settings';

          widget.disposed.connect(() => {
            content.dispose();
            content = null;
            widget = null;
            commands.notifyCommandChanged();
          });

          app.shell.add(widget, 'main');
          tracker.add(widget);

          widget.update();
          commands.notifyCommandChanged();
        }
      }
    });

    palette.addItem({ command, category: 'ROS' });

    const loadSetting = (setting: ISettingRegistry.ISettings): void => {
      const env = setting.get('env').composite as string;
      const master = setting.get('master').composite as string;

      if ( env != "" || master != "" ) {
        const msg = { method: 'PUT', body: JSON.stringify({ env, master }) };
  
        ServerConnection.makeRequest(url, msg, server)
        .then( resp => {})
        .catch( err => console.log(err) );
      }
    }

    settings.load('@robostack/jupyterlab-ros:settings')
      .then(rosSetting => {
        rosSetting.changed.connect(loadSetting);
        loadSetting(rosSetting);
      }).catch(err => console.log(err));
  }
}
Example #27
Source File: plugin.ts    From jupyter-videochat with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Create the public room plugin
 *
 * In the future, this might `provide` itself with some reasonable API,
 * but is already accessible from the manager, which is likely preferable.
 */
async function activatePublicRooms(
  app: JupyterFrontEnd,
  chat: IVideoChatManager,
  router?: IRouter,
  palette?: ICommandPalette
): Promise<void> {
  const { commands } = app;

  const { __ } = chat;

  chat.registerRoomProvider({
    id: 'public',
    label: __('Public'),
    rank: 999,
    provider: {
      updateRooms: async () => [],
      canCreateRooms: false,
      updateConfig: async () => {
        return {} as any;
      },
    },
  });

  commands.addCommand(CommandIds.togglePublicRooms, {
    label: __('Toggle Video Chat Public Rooms'),
    isVisible: () => !!chat.settings,
    isToggleable: true,
    isToggled: () => !chat.settings?.composite.disablePublicRooms,
    execute: async () => {
      if (!chat.settings) {
        console.warn(__('Video chat settings not loaded'));
        return;
      }
      await chat.settings.set(
        'disablePublicRooms',
        !chat.settings?.composite.disablePublicRooms
      );
    },
  });

  // If available, Add to the router
  if (router) {
    commands.addCommand(CommandIds.publicRouterStart, {
      label: __('Open Public Video Chat from URL'),
      execute: async (args) => {
        const { request } = args as IRouter.ILocation;
        const url = new URL(`http://example.com${request}`);
        const params = url.searchParams;
        const roomId = params.get(PUBLIC_URL_PARAM);

        const chatAfterRoute = async () => {
          router.routed.disconnect(chatAfterRoute);
          if (chat.currentRoom?.displayName != roomId) {
            chat.currentRoom = {
              id: roomId,
              displayName: roomId,
              description: __('A Public Room'),
            };
          }
        };

        router.routed.connect(chatAfterRoute);
      },
    });

    router.register({
      command: CommandIds.publicRouterStart,
      pattern: /.*/,
      rank: 99,
    });
  }

  // If available, add to command palette
  if (palette) {
    palette.addItem({ command: CommandIds.togglePublicRooms, category });
  }
}
Example #28
Source File: plugin.ts    From jupyter-videochat with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Handle application-level concerns
 */
async function activateCore(
  app: JupyterFrontEnd,
  settingRegistry: ISettingRegistry,
  translator?: ITranslator,
  palette?: ICommandPalette,
  launcher?: ILauncher,
  restorer?: ILayoutRestorer,
  mainmenu?: IMainMenu
): Promise<IVideoChatManager> {
  const { commands, shell } = app;

  const labShell = isFullLab(app) ? (shell as LabShell) : null;

  const manager = new VideoChatManager({
    trans: (translator || nullTranslator).load(NS),
  });

  const { __ } = manager;

  let widget: MainAreaWidget;
  let chat: VideoChat;
  let subject: string | null = null;

  const tracker = new WidgetTracker<MainAreaWidget>({ namespace: NS });

  if (!widget || widget.isDisposed) {
    // Create widget
    chat = new VideoChat(manager, {});
    widget = new MainAreaWidget({ content: chat });
    widget.addClass(`${CSS}-wrapper`);
    manager.setMainWidget(widget);

    widget.toolbar.addItem(ToolbarIds.SPACER_LEFT, Toolbar.createSpacerItem());

    widget.toolbar.addItem(ToolbarIds.TITLE, new RoomTitle(manager));

    widget.toolbar.addItem(ToolbarIds.SPACER_RIGHT, Toolbar.createSpacerItem());

    const disconnectBtn = new CommandToolbarButton({
      id: CommandIds.disconnect,
      commands,
      icon: stopIcon,
    });

    const onCurrentRoomChanged = () => {
      if (manager.currentRoom) {
        disconnectBtn.show();
      } else {
        disconnectBtn.hide();
      }
    };

    manager.currentRoomChanged.connect(onCurrentRoomChanged);

    widget.toolbar.addItem(ToolbarIds.DISCONNECT, disconnectBtn);

    onCurrentRoomChanged();

    chat.id = `id-${NS}`;
    chat.title.caption = __(DEFAULT_LABEL);
    chat.title.closable = false;
    chat.title.icon = chatIcon;
  }

  // hide the label when in sidebar, as it shows the rotated text
  function updateTitle() {
    if (subject != null) {
      widget.title.caption = subject;
    } else {
      widget.title.caption = __(DEFAULT_LABEL);
    }
    widget.title.label = manager.currentArea === 'main' ? widget.title.caption : '';
  }

  // add to shell, update tracker, title, etc.
  function addToShell(area?: ILabShell.Area, activate = true) {
    DEBUG && console.warn(`add to shell in are ${area}, ${!activate || 'not '} active`);
    area = area || manager.currentArea;
    if (labShell) {
      labShell.add(widget, area);
      updateTitle();
      widget.update();
      if (!tracker.has(widget)) {
        tracker.add(widget).catch(void 0);
      }
      if (activate) {
        shell.activateById(widget.id);
      }
    } else if (window.location.search.indexOf(FORCE_URL_PARAM) !== -1) {
      document.title = [document.title.split(' - ')[0], __(DEFAULT_LABEL)].join(' - ');
      app.shell.currentWidget.parent = null;
      app.shell.add(widget, 'main', { rank: 0 });
      const { parent } = widget;
      parent.addClass(`${CSS}-main-parent`);
      setTimeout(() => {
        parent.update();
        parent.fit();
        app.shell.fit();
        app.shell.update();
      }, 100);
    }
  }

  // listen for the subject to update the widget title dynamically
  manager.meetChanged.connect(() => {
    if (manager.meet) {
      manager.meet.on('subjectChange', (args: any) => {
        subject = args.subject;
        updateTitle();
      });
    } else {
      subject = null;
    }
    updateTitle();
  });

  // connect settings
  settingRegistry
    .load(corePlugin.id)
    .then((settings) => {
      manager.settings = settings;
      let lastArea = manager.settings.composite.area;
      settings.changed.connect(() => {
        if (lastArea !== manager.settings.composite.area) {
          addToShell();
        }
        lastArea = manager.settings.composite.area;
      });
      addToShell(null, false);
    })
    .catch(() => addToShell(null, false));

  // add commands
  commands.addCommand(CommandIds.open, {
    label: __(DEFAULT_LABEL),
    icon: prettyChatIcon,
    execute: async (args: IChatArgs) => {
      await manager.initialized;
      addToShell(null, true);
      // Potentially navigate to new room
      if (manager.currentRoom?.displayName !== args.displayName) {
        manager.currentRoom = { displayName: args.displayName };
      }
    },
  });

  commands.addCommand(CommandIds.disconnect, {
    label: __('Disconnect Video Chat'),
    execute: () => (manager.currentRoom = null),
    icon: stopIcon,
  });

  commands.addCommand(CommandIds.toggleArea, {
    label: __('Toggle Video Chat Sidebar'),
    icon: launcherIcon,
    execute: async () => {
      manager.currentArea = ['right', 'left'].includes(manager.currentArea)
        ? 'main'
        : 'right';
    },
  });

  // If available, add the commands to the palette
  if (palette) {
    palette.addItem({ command: CommandIds.open, category: __(category) });
  }

  // If available, add a card to the launcher
  if (launcher) {
    launcher.add({ command: CommandIds.open, args: { area: 'main' } });
  }

  // If available, restore the position
  if (restorer) {
    restorer
      .restore(tracker, { command: CommandIds.open, name: () => `id-${NS}` })
      .catch(console.warn);
  }

  // If available, add to the file->new menu.... new tab handled in retroPlugin
  if (mainmenu && labShell) {
    mainmenu.fileMenu.newMenu.addGroup([{ command: CommandIds.open }]);
  }

  // Return the manager that others extensions can use
  return manager;
}
Example #29
Source File: index.ts    From jlab-enhanced-launcher with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Activate the launcher.
 */
async function activate(
  app: JupyterFrontEnd,
  translator: ITranslator,
  labShell: ILabShell | null,
  palette: ICommandPalette | null,
  settingRegistry: ISettingRegistry | null,
  state: IStateDB | null
): Promise<ILauncher> {
  const { commands, shell } = app;
  const trans = translator.load('jupyterlab');

  let settings: ISettingRegistry.ISettings | null = null;
  if (settingRegistry) {
    try {
      settings = await settingRegistry.load(EXTENSION_ID);
    } catch (reason) {
      console.log(`Failed to load settings for ${EXTENSION_ID}.`, reason);
    }
  }

  const model = new LauncherModel(settings, state);

  if (state) {
    Promise.all([
      state.fetch(`${EXTENSION_ID}:usageData`),
      state.fetch(`${EXTENSION_ID}:viewMode`),
      app.restored
    ])
      .then(([usage, mode]) => {
        model.viewMode = (mode as any) || 'cards';
        for (const key in usage as any) {
          model.usage[key] = (usage as any)[key];
        }
      })
      .catch(reason => {
        console.error('Fail to restore launcher usage data', reason);
      });
  }

  commands.addCommand(CommandIDs.create, {
    label: trans.__('New Launcher'),
    execute: (args: ReadonlyPartialJSONObject) => {
      const cwd = args['cwd'] ? String(args['cwd']) : '';
      const id = `launcher-${Private.id++}`;
      const callback = (item: Widget): void => {
        shell.add(item, 'main', { ref: id });
      };
      const launcher = new Launcher({ model, cwd, callback, commands });

      launcher.model = model;
      launcher.title.icon = launcherIcon;
      launcher.title.label = trans.__('Launcher');

      const main = new MainAreaWidget({ content: launcher });

      // If there are any other widgets open, remove the launcher close icon.
      main.title.closable = !!toArray(shell.widgets('main')).length;
      main.id = id;

      shell.add(main, 'main', {
        activate: args['activate'] as boolean,
        ref: args['ref'] as string
      });

      if (labShell) {
        labShell.layoutModified.connect(() => {
          // If there is only a launcher open, remove the close icon.
          main.title.closable = toArray(labShell.widgets('main')).length > 1;
        }, main);
      }

      return main;
    }
  });

  if (palette) {
    palette.addItem({
      command: CommandIDs.create,
      category: trans.__('Launcher')
    });
  }

  if (labShell && app.version >= '3.4.0') {
    labShell.addButtonEnabled = true;
    labShell.addRequested.connect((sender: DockPanel, arg: TabBar<Widget>) => {
      // Get the ref for the current tab of the tabbar which the add button was clicked
      const ref =
        arg.currentTitle?.owner.id ||
        arg.titles[arg.titles.length - 1].owner.id;
      if (commands.hasCommand('filebrowser:create-main-launcher')) {
        // If a file browser is defined connect the launcher to it
        return commands.execute('filebrowser:create-main-launcher', { ref });
      }
      return commands.execute(CommandIDs.create, { ref });
    });
  }

  return model;
}