<commit_before>/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */

/*
A button that when clicked, shows a loading indicator until the backend
Jupyter notebook server is running, then pops it up in a new tab.
*/

import { join } from "path";
import { exec } from "../frame-editors/generic/client";
import { React, useIsMountedRef } from "smc-webapp/app-framework";
import { Icon, SettingBox } from "../r_misc";
import { LinkRetryUntilSuccess } from "../widgets-misc/link-retry";
import { useStudentProjectFunctionality } from "smc-webapp/course";

interface Props {
  project_id: string;
}

export const JupyterLabServerPanel: React.FC<Props> = ({ project_id }) => {
  const isMountedRef = useIsMountedRef();
  const student_project_functionality =
    useStudentProjectFunctionality(project_id);

  async function get_href(): Promise<string> {
    const url = await jupyterlab_server_url(project_id);
    if (!isMountedRef.current) {
      throw Error("unmounted");
    }
    return url;
  }

  function render_jupyter_link(): JSX.Element {
    return (
      <LinkRetryUntilSuccess get_href={get_href}>
        <Icon name="cc-icon-ipynb" /> JupyterLab Server
      </LinkRetryUntilSuccess>
    );
  }

  let body;
  if (student_project_functionality.disableJupyterLabServer) {
    body = "Disabled. Please contact your instructor if you need to use this.";
  } else {
    body = (
      <>
        <span style={{ color: "#444" }}>
          The JupyterLab server runs from your project and provides support for
          Jupyter notebooks, terminals, drag and drop, with a nice multiwindow
          layout, and much more. JupyterLab does not yet support multiple users
          or TimeTravel, but fully supports most Jupyter notebook features and
          extensions.
          <br />
          <br />
          Click the link below to start your Jupyter notebook server and open it
          in a new browser tab.
        </span>
        <div style={{ textAlign: "center", fontSize: "14pt", margin: "15px" }}>
          {render_jupyter_link()}
        </div>
      </>
    );
  }

  return (
    <SettingBox title="JupyterLab Server" icon="list-alt">
      {body}
    </SettingBox>
  );
};

export async function jupyterlab_server_url(
  project_id: string
): Promise<string> {
  const out = JSON.parse(
    (await exec({ project_id, command: "cc-jupyterlab", args: ["status"] }))
      .stdout
  );
  let port;
  if (out.status === "stopped") {
    port = JSON.parse(
      (await exec({ project_id, command: "cc-jupyterlab", args: ["start"] }))
        .stdout
    ).port;
  } else {
    port = out.port;
  }
  return join(window.app_base_path, project_id, "port", port);
}<commit_msg>fix bug in jupyterlab start component, caused by mistake in base_path revamp.<commit_after>/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */

/*
A button that when clicked, shows a loading indicator until the backend
Jupyter notebook server is running, then pops it up in a new tab.
*/

import { join } from "path";
import { exec } from "../frame-editors/generic/client";
import { React, useIsMountedRef } from "smc-webapp/app-framework";
import { Icon, SettingBox } from "../r_misc";
import { LinkRetryUntilSuccess } from "../widgets-misc/link-retry";
import { useStudentProjectFunctionality } from "smc-webapp/course";

interface Props {
  project_id: string;
}

export const JupyterLabServerPanel: React.FC<Props> = ({ project_id }) => {
  const isMountedRef = useIsMountedRef();
  const student_project_functionality =
    useStudentProjectFunctionality(project_id);

  async function get_href(): Promise<string> {
    const url = await jupyterlab_server_url(project_id);
    if (!isMountedRef.current) {
      throw Error("unmounted");
    }
    return url;
  }

  function render_jupyter_link(): JSX.Element {
    return (
      <LinkRetryUntilSuccess get_href={get_href}>
        <Icon name="cc-icon-ipynb" /> JupyterLab Server
      </LinkRetryUntilSuccess>
    );
  }

  let body;
  if (student_project_functionality.disableJupyterLabServer) {
    body = "Disabled. Please contact your instructor if you need to use this.";
  } else {
    body = (
      <>
        <span style={{ color: "#444" }}>
          The JupyterLab server runs from your project and provides support for
          Jupyter notebooks, terminals, drag and drop, with a nice multiwindow
          layout, and much more. JupyterLab does not yet support multiple users
          or TimeTravel, but fully supports most Jupyter notebook features and
          extensions.
          <br />
          <br />
          Click the link below to start your JupyterLab notebook server and open
          it in a new browser tab.
        </span>
        <div style={{ textAlign: "center", fontSize: "14pt", margin: "15px" }}>
          {render_jupyter_link()}
        </div>
      </>
    );
  }

  return (
    <SettingBox title="JupyterLab Server" icon="list-alt">
      {body}
    </SettingBox>
  );
};

export async function jupyterlab_server_url(
  project_id: string
): Promise<string> {
  const out = JSON.parse(
    (await exec({ project_id, command: "cc-jupyterlab", args: ["status"] }))
      .stdout
  );
  let port;
  if (out.status === "stopped") {
    port = JSON.parse(
      (await exec({ project_id, command: "cc-jupyterlab", args: ["start"] }))
        .stdout
    ).port;
  } else {
    port = out.port;
  }
  return join(window.app_base_path, project_id, "port", `${port}`);
}
{'fraction_non_alphanumeric': 0.11684397163120568, 'fraction_numerical': 0.00425531914893617, 'mean_word_length': 2.9978738483345144, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '404269', 'n_tokens_mistral': 1808, 'n_tokens_neox': 1771, 'n_words': 527}