@jupyterlab/apputils#MainAreaWidget TypeScript Examples

The following examples show how to use @jupyterlab/apputils#MainAreaWidget. 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: widget_manager.ts    From jupyter-extensions with Apache License 2.0 6 votes vote down vote up
launchWidgetForId(
    widgetType: new (...args: any[]) => ReactWidget,
    id: string,
    ...args: any[]
  ) {
    // Get the widget associated with a dataset/resource id, or create one
    // if it doesn't exist yet and activate it
    let widget = this.widgets[id];
    if (!widget || widget.isDisposed) {
      const content = new widgetType(...args);
      widget = new MainAreaWidget({ content });
      widget.disposed.connect(() => {
        if (this.widgets[id] === widget) {
          delete this.widgets[id];
        }
      });
      this.widgets[id] = widget;
    }
    if (!widget.isAttached) {
      this.app.shell.add(widget, 'main');
    }
    this.app.shell.activateById(widget.id);
  }
Example #2
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 #3
Source File: widget_manager.ts    From jupyter-extensions with Apache License 2.0 5 votes vote down vote up
private widgets: { [id: string]: MainAreaWidget } = {};
Example #4
Source File: bagWidget.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
export default class BagWidget extends MainAreaWidget<BagPanel> {

  private _play: Play;
  private _stop: Stop;
  private _running: Running;

  constructor(content: BagPanel) {
    super({ content });
    this.id = 'jupyterlab-ros/bag:widget';
    this.title.label = this.content.model.session.name;
    this.title.closable = true;

    this._play = new Play(this.onPlay);
    this.toolbar.addItem('play', this._play);

    this._stop = new Stop(this.onStop);
    this.toolbar.addItem('stop', this._stop);

    this._running = new Running();
    this.toolbar.addItem('running', this._running);

    this.content.model.statusChanged.connect(this._statusChanged, this);
  }

  dispose(): void {
    super.dispose();
    Signal.clearData(this);
  }

  onPlay = (event) => {
    this.content.model.play();
  }

  onStop = (event) => {
    this.content.model.stop();
  }

  private _statusChanged(sender: BagModel, status: string): void {
    if (status === "idle") {
      this._play.disable(false);
      this._stop.disable(true);
      this._running.disable(true);

    } else if (status == "busy") {
      this._play.disable(true);
      this._stop.disable(false);
      this._running.disable(false);
    }

    this.update();
  }
}
Example #5
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 #6
Source File: manager.ts    From jupyter-videochat with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
setMainWidget(widget: MainAreaWidget): void {
    if (this._mainWidget) {
      console.error(this.__('Main Video Chat widget already set'));
      return;
    }
    this._mainWidget = widget;
  }
Example #7
Source File: manager.ts    From jupyter-videochat with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
protected _mainWidget: MainAreaWidget;
Example #8
Source File: logConsoleWidget.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
export class LogConsoleWidget extends MainAreaWidget<LogConsolePanel> {
  
  private logs: RosLog[];
  private url: string;
  private ros: ROSLIB.Ros;
  private listener: ROSLIB.Topic;

  private status: LogStatus;
  private levelSwitcher: LogLevelSwitcher;
  private nodeSwicher: LogNodeSwitcher;

  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);
  }

  dispose(): void {
    this.listener?.unsubscribe();
    this.listener = null;
    this.ros?.close();
    this.ros = null;
    super.dispose();
  }

  private onConection = (): void => {
    this.status.setConnected(true);

    this.ros.getNodes((nodes) =>{
      this.nodeSwicher.refreshNodes(nodes);
    });
  }

  private onError = (error): void => {
    this.status.setConnected(false);

    /*showDialog({
      title: "Log Console: WARNING",
      body: <span className="jp-About-body">Master not running</span>,
      buttons: [Dialog.okButton()]
    }).catch( e => console.log(e) );*/
  }

  private onClose = (): void => {
    this.status.setConnected(false);
    
    setTimeout(() => {
      this.ros?.connect(this.url);
    }, 5000);
  }

  private onMessage = (msg): void => {
    const log: RosLog = {
      date: new Date(msg.header.stamp.secs * 1000),
      level: msg.level,
      name: msg.name,
      file: msg.file,
      function: msg.function,
      line: msg.line,
      topics: msg.topics,
      msg: msg.msg,
      toggled: false
    };
    
    this.logs.push(log);
    this.content.setLogs(this.logs);
    this.nodeSwicher.setNode(msg.name);
  }

  public checkpoint = (): void => {
    const log: RosLog = {
      date: new Date(),
      level: 0,
      name: "",
      file: "",
      function: "",
      line: 0,
      topics: [],
      msg: "",
      toggled: false
    };
    this.logs.push(log);
    this.content.setLogs(this.logs);
  }
  
  public clear = (): void => {
    this.logs = [];
    this.content.setLogs(this.logs);
    this.ros.getNodes((nodes) =>{
      this.nodeSwicher.refreshNodes(nodes);
    });
  }
}
Example #9
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;
}
Example #10
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;
}