@jupyterlab/apputils#showDialog TypeScript Examples

The following examples show how to use @jupyterlab/apputils#showDialog. 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: status.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
// console.log(event); }
  onMessage = (message) => {
    const msg = JSON.parse(message.data);
    const body = document.createElement('div');
    
    switch (msg.code) {
      case 0: this.paths = msg.paths; break;
      case 1: this.paths.push(msg.path); break;
      case 2:
        renderText({host: body, sanitizer: defaultSanitizer, source: msg.msg });
        showDialog({
          title: "WARNING: " + msg.path,
          body: <div className=".jp-RenderedText" dangerouslySetInnerHTML={{ __html: body.innerHTML }}></div>,
          buttons: [ Dialog.okButton() ]
        });
        break;
      case 3:
      case 4:
        var index = this.paths.indexOf(msg.path);
        if (index !== -1) this.paths.splice(index, 1);

        renderText({host: body, sanitizer: defaultSanitizer, source: msg.msg });
        showDialog({
          title: (msg.code == 3 ? "FINISHED: " : "ERROR: " ) + msg.path,
          body: <div className=".jp-RenderedText" dangerouslySetInnerHTML={{ __html: body.innerHTML }}></div>,
          buttons: [ Dialog.okButton() ]
        });
        break;
      
      default:
        break;
    }
    this.update();
  }
Example #2
Source File: status.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
toggle = (path) => {
    showDialog({
      title: path,
      body: <pre className=".jp-RenderedText">This execution will be stoped. Are you sure?</pre>,
      buttons: [ Dialog.okButton(), Dialog.cancelButton() ]
    }).then(res => {
      if (res.button.label != "OK") return;
      this.ws.send( JSON.stringify({ cmd: 'stop', path }) );

    }).catch( e => console.log(e) );
  }
Example #3
Source File: status.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
onMessage = (message) => {
    const msg = JSON.parse(message.data);
    
    if (msg['error']) {
      const body = document.createElement('div');
      renderText({host: body, sanitizer: defaultSanitizer, source: msg['error'] });

      showDialog({
        title: "Master: WARNING",
        body: <div className=".jp-RenderedText" dangerouslySetInnerHTML={{ __html: body.innerHTML }} />,
        buttons: [ Dialog.okButton() ]
      });

    } else if (msg['output']) {
      const body = document.createElement('div');
      renderText({host: body, sanitizer: defaultSanitizer, source: msg['output'] });

      showDialog({
        title: "Master FINNISHED",
        body: <div className=".jp-RenderedText" dangerouslySetInnerHTML={{ __html: body.innerHTML }} />,
        buttons: [ Dialog.okButton() ]
      });
    }

    this.status = msg['status'];
    this.update();
  }
Example #4
Source File: status.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
start = () => {
    showDialog({
      title: "Master",
      body: <pre className=".jp-RenderedText">Do you want to START ROS Master?</pre>,
      buttons: [ Dialog.okButton(), Dialog.cancelButton() ]
    }).then(res => {
      if (res.button.label != "OK") return;
      this.ws.send(JSON.stringify({ cmd: "start" }));
    }).catch( e => console.log(e) );
  }
Example #5
Source File: status.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
stop = () => {
    showDialog({
      title: "Master",
      body: <pre className=".jp-RenderedText">Do you want to STOP ROS Master?</pre>,
      buttons: [ Dialog.okButton(), Dialog.cancelButton() ]
    }).then(res => {
      if (res.button.label != "OK") return;
      this.ws.send(JSON.stringify({ cmd: "stop" }));
    }).catch( e => console.log(e) );
  }
Example #6
Source File: reactWidget.tsx    From ipyflex with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
saveTemplate = async (): Promise<void> => {
    const oldTemplate = this.props.model.get('template');

    const result = await showDialog<string>(
      dialogBody('Save template', oldTemplate)
    );
    if (result.button.label === 'Save') {
      const fileName = result.value;
      if (fileName) {
        this.props.send_msg({
          action: MESSAGE_ACTION.SAVE_TEMPLATE,
          payload: {
            file_name: result.value,
            json_data: this.state.model.toJson(),
          },
        });
      } else {
        alert('Invalid file name!');
      }
    }
  };
Example #7
Source File: reactWidget.tsx    From ipyflex with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
exportTemplate = async (): Promise<void> => {
    const result = await showDialog<string>(
      dialogBody('Export template', null, 'Export')
    );
    if (result.button.label === 'Export') {
      let fileName = result.value;
      if (fileName) {
        fileName = fileName.replace('.json', '') + '.json';
        const jsonString = this.state.model.toString();
        downloadString(jsonString, 'application/json', fileName);
      } else {
        alert('Invalid file name!');
      }
    }
  };
Example #8
Source File: index.ts    From jupyterlab-gitplus with GNU Affero General Public License v3.0 5 votes vote down vote up
export function show_spinner() {
  const spinWidget = new SpinnerDialog();
  showDialog({
    title: 'Waiting for response...',
    body: spinWidget,
    buttons: [Dialog.cancelButton()]
  }).then(result => { });
}
Example #9
Source File: bagPanel.tsx    From jupyterlab-ros with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
render(): JSX.Element {
    if (this._model?.error) {
      const body = document.createElement('div');
      renderText({host: body, sanitizer: defaultSanitizer, source: this._model?.error });

      showDialog({
        title: "ERROR Bag: " + this._model.session.name,
        body: <div className=".jp-RenderedText" dangerouslySetInnerHTML={{ __html: body.innerHTML }} />,
        buttons: [ Dialog.okButton() ]
      });
    }

    return (
      <div className="bagPanel">
        { this._isLoading ?
            <div className="loader"> <div className="lds-ring"><div></div><div></div><div></div><div></div></div> </div>
          :
            <div className="bag">
              <div>Path: {this._model.bag?.path}</div>
              <div>Version: {this._model.bag?.version}</div>
              <div>Duration: {this._model.bag?.duration}</div>
              <div>Start: {this._model.bag?.start}</div>
              <div>End: {this._model.bag?.end}</div>
              <div>Size: {this._model.bag?.size}</div>
              <div>Messages: {this._model.bag?.messages}</div>
              <div>Compresion: {this._model.bag?.compression}</div>
              
              <div onClick={()=>{ this._showTypes(true); }}>
                Types: { !this._isTypesVisible &&
                  <runIcon.react tag="span" top="5px" width="14px" height="14px" />
                }
              </div>
              { this._isTypesVisible && 
                <table onClick={() => {this._showTypes(false);}} style={{paddingLeft: "15px"}}>
                  <tbody>
                    {this._model.bag?.types.map( type => {
                      return (<tr key={type.type}><td>{type.type}</td><td>{type.hash}</td></tr>);
                    })}
                  </tbody>
                </table>
              }

              <div onClick={() => {this._showTopics(true);}}>
                Topics: { !this._isTopicsVisible &&
                  <runIcon.react tag="span" top="5px" width="14px" height="14px" />
                }
              </div>
              
              { this._isTopicsVisible &&
                <table onClick={() => {this._showTopics(false);}} style={{paddingLeft: "15px"}}>
                  <tbody>
                    <tr><th>Topic</th><th>Message type</th><th>Message count</th><th>Connections</th><th>Frequency</th></tr>
                    {this._model.bag?.topics?.map( topic => {
                      return (<tr key={topic.topic}><td>{topic.topic}</td><td>{topic.msg_type}</td><td>{topic.message_count}</td><td>{topic.connections}</td><td>{topic.frequency}</td></tr>);
                    })}
                  </tbody>
                </table>
              }
            </div>
        }
      </div>
    );
  }
Example #10
Source File: index.ts    From jupyterlab-gitplus with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * Activate the extension.
 */
function activate(
  app: JupyterFrontEnd,
  mainMenu: IMainMenu,
  editorTracker: IEditorTracker,
  notebookTracker: INotebookTracker
) {
  console.log(
    'JupyterLab extension @reviewnb/gitplus (0.1.5) is activated!'
  );
  const createPRCommand = 'create-pr';
  app.commands.addCommand(createPRCommand, {
    label: 'Create Pull Request',
    execute: () => {
      get_server_config()
        .then(config => {
          const files = get_open_files(
            editorTracker,
            notebookTracker,
            config['server_root_dir']
          );
          const data = get_json_request_payload_from_file_list(files);
          get_modified_repositories(
            data,
            show_repository_selection_dialog,
            createPRCommand,
            show_repository_selection_failure_dialog
          );
        })
        .catch(error => {
          show_repository_selection_failure_dialog();
          console.log(error);
        });
    }
  });

  const pushCommitCommand = 'push-commit';
  app.commands.addCommand(pushCommitCommand, {
    label: 'Push Commit',
    execute: () => {
      get_server_config()
        .then(config => {
          const files = get_open_files(
            editorTracker,
            notebookTracker,
            config['server_root_dir']
          );
          const data = get_json_request_payload_from_file_list(files);
          get_modified_repositories(
            data,
            show_repository_selection_dialog,
            pushCommitCommand,
            show_repository_selection_failure_dialog
          );
        })
        .catch(error => {
          show_repository_selection_failure_dialog();
          console.log(error);
        });
    }
  });

  function show_repository_selection_dialog(
    repo_names: string[][],
    command: string
  ) {
    if (repo_names.length == 0) {
      let msg =
        "No GitHub repositories found! \n\nFirst, open the files that you'd like to commit or create pull request for.";
      if (command == createPRCommand) {
        msg =
          "No GitHub repositories found! \n\nFirst, open the files that you'd like to create pull request for.";
      } else if (command == pushCommitCommand) {
        msg =
          "No GitHub repositories found! \n\nFirst, open the files that you'd like to commit.";
      }
      showDialog({
        title: 'Repository Selection',
        body: msg,
        buttons: [Dialog.okButton({ label: 'Okay' })]
      }).then(result => { });
    } else {
      const label_style = {
        'font-size': '14px'
      };
      const body_style = {
        'padding-top': '2em',
        'padding-bottom': '2em',
        'border-top': '1px solid #dfe2e5'
      };
      const select_style = {
        'margin-top': '4px',
        'min-height': '32px'
      };
      const styles = {
        label_style: label_style,
        body_style: body_style,
        select_style: select_style
      };
      const dwidget = new DropDown(repo_names, 'Select Repository', styles);
      showDialog({
        title: 'Repository Selection',
        body: dwidget,
        buttons: [Dialog.cancelButton(), Dialog.okButton({ label: 'Next' })]
      }).then(result => {
        if (!result.button.accept) {
          return;
        }
        const repo_name = dwidget.getTo();
        show_file_selection_dialog(repo_name, command);
      });
    }
  }

  function show_file_selection_dialog(repo_path: string, command: string) {
    get_server_config()
      .then(config => {
        const files = get_open_files(
          editorTracker,
          notebookTracker,
          config['server_root_dir']
        );
        const relevant_files: string[] = [];

        for (const f of files) {
          if (f.startsWith(repo_path)) {
            relevant_files.push(f.substring(repo_path.length + 1));
          }
        }

        const cwidget = new CheckBoxes(relevant_files);
        showDialog({
          title: 'Select Files',
          body: cwidget,
          buttons: [Dialog.cancelButton(), Dialog.okButton({ label: 'Next' })]
        }).then(result => {
          if (!result.button.accept) {
            return;
          }
          const files = cwidget.getSelected();

          if (command == createPRCommand) {
            show_commit_pr_message_dialog(repo_path, files);
          } else if (command == pushCommitCommand) {
            show_commit_message_dialog(repo_path, files);
          }
        });
      })
      .catch(error => {
        show_file_selection_failure_dialog();
        console.log(error);
      });
  }

  function show_commit_message_dialog(repo_path: string, files: string[]) {
    console.log(`${repo_path} --show_commit_message_dialog-- ${files}`);
    const cmwidget = new CommitMessageDialog();

    showDialog({
      title: 'Provide Details',
      body: cmwidget,
      buttons: [
        Dialog.cancelButton(),
        Dialog.okButton({ label: 'Create & Push Commit' })
      ]
    }).then(result => {
      if (!result.button.accept) {
        return;
      }
      const commit_message = cmwidget.getCommitMessage();
      const body = {
        files: files,
        repo_path: repo_path,
        commit_message: commit_message
      };
      create_and_push_commit(body, show_commit_pushed_dialog);
    });
  }

  function show_commit_pr_message_dialog(repo_path: string, files: string[]) {
    console.log(`${repo_path} --show_commit_pr_message_dialog-- ${files}`);
    const cprwidget = new CommitPRMessageDialog();

    showDialog({
      title: 'Provide Details',
      body: cprwidget,
      buttons: [Dialog.cancelButton(), Dialog.okButton({ label: 'Create PR' })]
    }).then(result => {
      if (!result.button.accept) {
        return;
      }
      const commit_message = cprwidget.getCommitMessage();
      const pr_title = cprwidget.getPRTitle();
      const body = {
        files: files,
        repo_path: repo_path,
        commit_message: commit_message,
        pr_title: pr_title
      };
      create_pull_request(body, show_pr_created_dialog);
    });
  }

  function show_pr_created_dialog(github_url = '', reviewnb_url = '') {
    if (github_url.length == 0 || reviewnb_url.length == 0) {
      showDialog({
        title: 'Failure',
        body: "Failed to create pull request. Check Jupyter logs for error. \n\nMake sure you've correctly setup GitHub access token. Steps here - https://github.com/ReviewNB/jupyterlab-gitplus/blob/master/README.md#setup-github-token\n\nIf unable to resolve, open an issue here - https://github.com/ReviewNB/jupyterlab-gitplus/issues",
        buttons: [Dialog.okButton({ label: 'Okay' })]
      }).then(result => { });
    } else {
      const prcwidget = new PRCreated(github_url, reviewnb_url);

      showDialog({
        title: 'Pull Request Created',
        body: prcwidget,
        buttons: [Dialog.cancelButton(), Dialog.okButton({ label: 'Okay' })]
      }).then(result => { });
    }
  }

  function show_commit_pushed_dialog(github_url = '', reviewnb_url = '') {
    if (github_url.length == 0 || reviewnb_url.length == 0) {
      showDialog({
        title: 'Failure',
        body: 'Failed to create/push commit. Check Jupyter logs for error. \n\nIf unable to resolve, open an issue here - https://github.com/ReviewNB/jupyterlab-gitplus/issues',
        buttons: [Dialog.okButton({ label: 'Okay' })]
      }).then(result => { });
    } else {
      const prcwidget = new CommitPushed(github_url, reviewnb_url);

      showDialog({
        title: 'Commit pushed!',
        body: prcwidget,
        buttons: [Dialog.cancelButton(), Dialog.okButton({ label: 'Okay' })]
      }).then(result => {
        if (!result.button.accept) {
          return;
        }
      });
    }
  }
  // Create new top level menu
  const menu = new Menu({ commands: app.commands });
  menu.title.label = 'Git-Plus';
  mainMenu.addMenu(menu, { rank: 40 });

  // Add commands to menu
  menu.addItem({
    command: createPRCommand,
    args: {}
  });
  menu.addItem({
    command: pushCommitCommand,
    args: {}
  });
}
Example #11
Source File: index.ts    From jupyterlab-interactive-dashboard-editor with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Add commands to the main JupyterLab command registry.
 *
 * @param app - the JupyterLab instance.
 *
 * @param dashboardTracker - a tracker for dashboards.
 *
 * @param outputTracker - a tracker for dashboard outputs.
 *
 * @param clipboard - a set used to keep track of widgets for copy/pasting.
 *
 * @param docManager - a document manager used to create/rename files.
 *
 * @param notebookTracker - a tracker for notebooks.
 */
function addCommands(
  app: JupyterFrontEnd,
  dashboardTracker: WidgetTracker<Dashboard>,
  outputTracker: WidgetTracker<DashboardWidget>,
  clipboard: Set<Widgetstore.WidgetInfo>,
  docManager: IDocumentManager,
  notebookTracker: INotebookTracker
): void {
  const { commands } = app;

  /**
   * Whether there is an active dashboard.
   */
  function hasDashboard(): boolean {
    return dashboardTracker.currentWidget !== null;
  }

  /**
   * Whether there is a dashboard output.
   */
  function hasOutput(): boolean {
    return outputTracker.currentWidget !== null;
  }

  function inToolbar(args: ReadonlyJSONObject): boolean {
    return args.toolbar as boolean;
  }

  /**
   * Deletes a selected DashboardWidget.
   */
  commands.addCommand(CommandIDs.deleteOutput, {
    label: 'Delete Output',
    execute: args => {
      const widget = outputTracker.currentWidget;
      const dashboard = dashboardTracker.currentWidget;
      dashboard.deleteWidget(widget);
    }
  });

  /**
   * Undo the last change to a dashboard.
   */
  commands.addCommand(CommandIDs.undo, {
    label: args => (inToolbar(args) ? '' : 'Undo'),
    icon: undoIcon,
    execute: args => {
      dashboardTracker.currentWidget.undo();
    },
    isEnabled: args =>
      inToolbar(args) ||
      (dashboardTracker.currentWidget &&
        dashboardTracker.currentWidget.model.widgetstore.hasUndo())
  });

  /**
   * Redo the last undo to a dashboard.
   */
  commands.addCommand(CommandIDs.redo, {
    label: args => (inToolbar(args) ? '' : 'Redo'),
    icon: redoIcon,
    execute: args => {
      dashboardTracker.currentWidget.redo();
    },
    isEnabled: args =>
      inToolbar(args) ||
      (dashboardTracker.currentWidget &&
        dashboardTracker.currentWidget.model.widgetstore.hasRedo())
  });

  commands.addCommand(CommandIDs.toggleFitContent, {
    label: args => 'Fit To Content',
    execute: args => {
      const widget = outputTracker.currentWidget;
      widget.fitToContent = !widget.fitToContent;
      if (widget.fitToContent) {
        widget.fitContent();
      }
    },
    isVisible: args => outputTracker.currentWidget.mode === 'free-edit',
    isToggled: args => outputTracker.currentWidget.fitToContent
  });

  commands.addCommand(CommandIDs.toggleMode, {
    icon: args => {
      const mode = dashboardTracker.currentWidget?.model.mode || 'present';
      if (mode === 'present') {
        return DashboardIcons.edit;
      } else {
        return DashboardIcons.view;
      }
    },
    label: args => {
      if (inToolbar(args)) {
        return '';
      }
      const mode = dashboardTracker.currentWidget?.model.mode || 'present';
      if (mode === 'present') {
        return 'Switch To Edit Mode';
      } else {
        return 'Switch To Presentation Mode';
      }
    },
    execute: args => {
      const dashboard = dashboardTracker.currentWidget;
      if (dashboard.model.mode === 'present') {
        dashboard.model.mode = 'free-edit';
      } else {
        dashboard.model.mode = 'present';
      }
    }
  });

  commands.addCommand(CommandIDs.runOutput, {
    label: args => (inToolbar(args) ? '' : 'Run Output'),
    icon: runIcon,
    execute: args => {
      const widget = outputTracker.currentWidget;
      const sessionContext = widget.notebook.sessionContext;
      CodeCell.execute(widget.cell as CodeCell, sessionContext);
    }
  });

  commands.addCommand(CommandIDs.setDimensions, {
    label: 'Set Dashboard Dimensions',
    execute: async args => {
      const model = dashboardTracker.currentWidget.model;
      const width = model.width ? model.width : Dashboard.DEFAULT_WIDTH;
      const height = model.height ? model.height : Dashboard.DEFAULT_HEIGHT;
      await showDialog({
        title: 'Enter Dimensions',
        body: new Private.ResizeHandler(width, height),
        focusNodeSelector: 'input',
        buttons: [Dialog.cancelButton(), Dialog.okButton()]
      }).then(result => {
        const value = result.value;
        let newWidth = value[0];
        let newHeight = value[1];
        if (value === null && model.width && model.height) {
          return;
        }
        if (!newWidth) {
          if (!model.width) {
            newWidth = Dashboard.DEFAULT_WIDTH;
          } else {
            newWidth = model.width;
          }
        }
        if (!newHeight) {
          if (!model.height) {
            newHeight = Dashboard.DEFAULT_HEIGHT;
          } else {
            newHeight = model.height;
          }
        }
        model.width = newWidth;
        model.height = newHeight;
      });
    },
    isEnabled: hasDashboard
  });

  commands.addCommand(CommandIDs.setTileSize, {
    label: 'Set Grid Dimensions',
    execute: async args => {
      const newSize = await InputDialog.getNumber({
        title: 'Enter Grid Size'
      });
      if (newSize.value) {
        const layout = dashboardTracker.currentWidget.layout as DashboardLayout;
        layout.setTileSize(newSize.value);
      }
    },
    isEnabled: hasDashboard
  });

  commands.addCommand(CommandIDs.copy, {
    label: args => (inToolbar(args) ? '' : 'Copy'),
    icon: copyIcon,
    execute: args => {
      const info = outputTracker.currentWidget.info;
      clipboard.clear();
      clipboard.add(info);
    },
    isEnabled: args => inToolbar(args) || hasOutput()
  });

  commands.addCommand(CommandIDs.cut, {
    label: args => (inToolbar(args) ? '' : 'Cut'),
    icon: cutIcon,
    execute: args => {
      const widget = outputTracker.currentWidget;
      const info = widget.info;
      const dashboard = dashboardTracker.currentWidget;
      clipboard.clear();
      clipboard.add(info);
      dashboard.deleteWidget(widget);
    },
    isEnabled: args => inToolbar(args) || hasOutput()
  });

  commands.addCommand(CommandIDs.paste, {
    label: args => (inToolbar(args) ? '' : 'Paste'),
    icon: pasteIcon,
    execute: args => {
      const id = args.dashboardId;
      let dashboard: Dashboard;
      if (id) {
        dashboard = dashboardTracker.find(widget => widget.id === id);
      } else {
        dashboard = dashboardTracker.currentWidget;
      }
      const widgetstore = dashboard.model.widgetstore;
      clipboard.forEach(info => {
        const widgetId = DashboardWidget.createDashboardWidgetId();
        const pos = info.pos;
        pos.left = Math.max(pos.left - 10, 0);
        pos.top = Math.max(pos.top - 10, 0);

        const newWidget = widgetstore.createWidget({ ...info, widgetId, pos });
        dashboard.addWidget(newWidget, pos);
      });
    },
    isEnabled: args => inToolbar(args) || (hasOutput() && clipboard.size !== 0)
  });

  commands.addCommand(CommandIDs.saveToMetadata, {
    label: 'Save Dashboard To Notebook Metadata',
    execute: args => {
      const dashboard = dashboardTracker.currentWidget;
      dashboard.saveToNotebookMetadata();
    }
  });

  commands.addCommand(CommandIDs.createNew, {
    label: 'Dashboard',
    icon: DashboardIcons.tealDashboard,
    execute: async args => {
      // A new file is created and opened separately to override the default
      // opening behavior when there's a notebook and open the dashboard in a
      // split pane instead of a tab.

      const notebook = notebookTracker.currentWidget;
      const newModel = await docManager.newUntitled({
        ext: 'dash',
        path: '/',
        type: 'file'
      });
      const path = newModel.path;
      if (notebook) {
        docManager.openOrReveal(`/${path}`, undefined, undefined, {
          mode: 'split-left',
          ref: notebook.id
        });
      } else {
        docManager.openOrReveal(`/${path}`);
      }
    }
  });

  // TODO: Make this optionally saveAs (based on filename?)
  commands.addCommand(CommandIDs.save, {
    label: args => (inToolbar(args) ? '' : 'Save'),
    icon: saveIcon,
    execute: args => {
      const dashboard = dashboardTracker.currentWidget;
      dashboard.context.save();
    },
    isEnabled: args => inToolbar(args) || hasDashboard()
  });

  commands.addCommand(CommandIDs.openFromMetadata, {
    label: 'Open Metadata Dashboard',
    execute: args => {
      const notebook = notebookTracker.currentWidget;
      const notebookMetadata = getMetadata(notebook);
      const notebookId = notebookMetadata.id;
      const cells = notebook.content.widgets;

      const widgetstore = new Widgetstore({ id: 0, notebookTracker });

      widgetstore.startBatch();

      for (const cell of cells) {
        const metadata = getMetadata(cell);
        if (metadata !== undefined && !metadata.hidden) {
          const widgetInfo: WidgetInfo = {
            widgetId: DashboardWidget.createDashboardWidgetId(),
            notebookId,
            cellId: metadata.id,
            pos: metadata.pos
          };
          widgetstore.addWidget(widgetInfo);
        }
      }

      widgetstore.endBatch();

      const model = new DashboardModel({
        widgetstore,
        notebookTracker
      });

      const dashboard = new Dashboard({
        outputTracker,
        model
      });

      dashboard.updateLayoutFromWidgetstore();
      dashboard.model.mode = 'present';

      notebook.context.addSibling(dashboard, { mode: 'split-left' });
    },
    isEnabled: args => {
      const notebook = notebookTracker.currentWidget;
      const metadata = getMetadata(notebook);
      if (metadata !== undefined && metadata.hasDashboard !== undefined) {
        return metadata.hasDashboard;
      }
      return false;
    }
  });

  commands.addCommand(CommandIDs.toggleWidgetMode, {
    label: 'Snap to Grid',
    isToggled: args => {
      const widget = outputTracker.currentWidget;
      return widget.mode === 'grid-edit';
    },
    execute: args => {
      const widget = outputTracker.currentWidget;
      if (widget.mode === 'grid-edit') {
        widget.mode = 'free-edit';
      } else if (widget.mode === 'free-edit') {
        widget.mode = 'grid-edit';
      }
    }
  });

  commands.addCommand(CommandIDs.toggleInfiniteScroll, {
    label: 'Infinite Scroll',
    isToggled: args =>
      dashboardTracker.currentWidget?.model.scrollMode === 'infinite',
    execute: args => {
      const dashboard = dashboardTracker.currentWidget;
      if (dashboard.model.scrollMode === 'infinite') {
        dashboard.model.scrollMode = 'constrained';
      } else {
        dashboard.model.scrollMode = 'infinite';
      }
    }
  });

  commands.addCommand(CommandIDs.trimDashboard, {
    label: 'Trim Dashboard',
    execute: args => {
      const dashboard = dashboardTracker.currentWidget;
      (dashboard.layout as DashboardLayout).trimDashboard();
    }
  });
}
Example #12
Source File: menuWidget.tsx    From ipyflex with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
render(): JSX.Element {
    const menuId = `add_widget_menu_${this.props.tabsetId}@${this.props.nodeId}`;
    const widgetItems = [];
    for (const name of [
      ...this.state.widgetList,
      ...this.state.placeholderList,
    ]) {
      if (name !== CREATE_NEW) {
        widgetItems.push(
          <MenuItem
            key={`${name}}@${this.props.tabsetId}@${this.props.nodeId}`}
            onClick={() => {
              this.props.addTabToTabset(name);
              this.handleClose();
            }}
          >
            {name}
          </MenuItem>
        );
      }
    }

    const factoryItems = [];
    for (const [name, signature] of Object.entries(this.props.factoryDict)) {
      factoryItems.push(
        <MenuItem
          key={`${name}}@${this.props.tabsetId}@${this.props.nodeId}`}
          onClick={async () => {
            this.handleClose();
            const paramList = Object.keys(signature);
            if (paramList.length > 0) {
              const result = await showDialog<IDict<string>>(
                factoryDialog('Factory parameters', signature)
              );
              if (result.button.label === 'Create' && result.value) {
                this.props.addTabToTabset(name, result.value);
              } else {
                return;
              }
            } else {
              this.props.addTabToTabset(name);
            }
          }}
        >
          {name}
        </MenuItem>
      );
    }

    const createNew: JSX.Element = (
      <MenuItem
        key={`$#{this.props.tabsetId}@${this.props.nodeId}`}
        onClick={async () => {
          this.handleClose();
          let widgetName: string;
          const result = await showDialog<string>(
            dialogBody('Widget name', '')
          );
          if (result.button.label === 'Save' && result.value) {
            widgetName = result.value;
            if (this.state.widgetList.includes(widgetName)) {
              alert('A widget with the same name is already registered!');
              return;
            }
            if (widgetName in this.props.factoryDict) {
              alert('A factory with the same name is already registered!');
              return;
            }
            this.props.send_msg({
              action: MESSAGE_ACTION.ADD_WIDGET,
              payload: { name: widgetName },
            });
          } else {
            return;
          }

          this.props.addTabToTabset(widgetName);
        }}
      >
        {CREATE_NEW}
      </MenuItem>
    );
    // menuItem.push(createNew);
    return (
      <div key={menuId}>
        <button
          className={JUPYTER_BUTTON_CLASS}
          style={{ height: '27px', width: '40px' }}
          onClick={this.handleClick}
        >
          <i className="fas fa-plus"></i>
        </button>
        <Menu
          id="simple-menu"
          anchorEl={this.state.anchorEl}
          keepMounted
          open={Boolean(this.state.anchorEl)}
          onClose={this.handleClose}
          anchorOrigin={{
            vertical: 'bottom',
            horizontal: 'center',
          }}
          transformOrigin={{
            vertical: 'top',
            horizontal: 'center',
          }}
        >
          {widgetItems}
          <hr className="ipyflex-divider" />
          {factoryItems}
          {Object.keys(this.props.factoryDict).length > 0 ? (
            <hr className="ipyflex-divider" />
          ) : (
            <div />
          )}

          {createNew}
        </Menu>
      </div>
    );
  }