Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/next/components/share/edit/choose-project.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { join } from "path";6import { useEffect, useState } from "react";7import { Alert, Button, Checkbox, Space } from "antd";8import useIsMounted from "lib/hooks/mounted";9import { path_split, trunc } from "@cocalc/util/misc";10import copyPublicPath from "lib/share/copy-public-path";11import Loading from "components/share/loading";12import api from "lib/api/post";13import A from "components/misc/A";14import ProjectListing from "components/project/listing";15import CreateProject from "components/project/create";16import SelectProject from "components/project/select";17import editURL from "lib/share/edit-url";18import { Icon } from "@cocalc/frontend/components/icon";19import RunApp from "components/app/path";20import useCustomize from "lib/use-customize";2122interface Props {23id;24src_project_id;25path;26url;27relativePath;28everything;29image;30description;31onCopied;32}3334export default function ChooseProject(props: Props) {35const {36id,37src_project_id,38path,39url,40relativePath,41everything,42image,43description,44onCopied,45} = props;46const isMounted = useIsMounted();47const { defaultComputeImage } = useCustomize();48const [project, setProject] = useState<49{ project_id: string; title: string } | undefined50>(undefined);51const [copying, setCopying] = useState<52"before" | "starting" | "during" | "after"53>("before");54const [errorCopying, setErrorCopying] = useState<string>("");55const [showListing, setShowListing] = useState<boolean>(false);56const [hideSelect, setHideSelect] = useState<boolean>(false);57const [hideCreate, setHideCreate] = useState<boolean>(false);58const [createdProject, setCreatedProject] = useState<boolean>(false);59const targetPath = url60? path_split(join(path, relativePath)).tail61: join(path, relativePath);6263useEffect(() => {64// Always immediately start copying -- don't wait for user to click a button. See65// https://github.com/sagemathinc/cocalc/issues/602566if (project != null && copying == "before") {67doCopy();68}69}, [project != null]);7071async function doCopy() {72try {73if (project == null) throw Error("no target specified");74setCopying("starting");75setHideSelect(true);76if (!createdProject) {77// Possibly upgrade the project using a public_path license. Only do this if we78// didn't just create the project, since in that case the license would already79// be applied during creation.80await api("/projects/public-path-license", {81public_path_id: id,82project_id: project.project_id,83});84}85// Start the *target* project!86await api("/projects/start", { project_id: project.project_id });87if (!isMounted.current) return;88setCopying("during");89// Get the content90if (url) {91// From a URL (e.g. github)92await api("/projects/copy-url", {93project_id: project.project_id,94url,95path: targetPath,96});97} else {98// From another project99await copyPublicPath({100id,101src_project_id,102path,103url,104relativePath: everything ? "" : relativePath, // "" = so *everything* is copied105target_project_id: project.project_id,106});107}108} catch (err) {109if (!isMounted.current) return;110setErrorCopying(err.message);111} finally {112if (!isMounted.current) return;113setCopying("after");114onCopied();115}116}117118return (119<div>120<div>121{!errorCopying && copying == "after" && project?.project_id && (122<RunApp start project_id={project.project_id} path={targetPath} />123)}124{image && image != defaultComputeImage && (125<div>126We recommend that you create a new project, since this public path127uses the non-default image "{image}".128</div>129)}130{!hideCreate && (131<CreateProject132image={image}133label="In a new project"134start={true}135public_path_id={id}136defaultTitle={url ? targetPath : description}137onCreate={(project) => {138setCreatedProject(true);139setProject(project);140setHideSelect(true);141setHideCreate(true);142}}143/>144)}145{!hideSelect && (146<SelectProject147label="In one of your existing projects"148onChange={({ project_id, title }) => {149setCreatedProject(false);150setProject({ project_id, title });151setHideCreate(true);152}}153/>154)}155</div>{" "}156{project && (157<Space158direction="vertical"159style={{ width: "100%", marginTop: "15px" }}160>161<div style={{ textAlign: "center" }}>162{copying == "before" && (163<>164<Button165onClick={doCopy}166size="large"167type="primary"168style={{ maxWidth: "100%", overflow: "hidden" }}169shape="round"170>171<Icon name="copy" /> Copy {targetPath} to172<b style={{ marginLeft: "5px" }}>{project.title}</b>173</Button>174{!hideSelect && (175<Checkbox176disabled={!project}177style={{178float: "right",179marginTop: "15px",180fontSize: "10pt",181color: "#666",182}}183onChange={(e) => setShowListing(e.target.checked)}184>185Show contents of{" "}186<A187href={editURL({188type: "collaborator",189project_id: project.project_id,190})}191external192>193{trunc(project.title, 30)}194</A>195</Checkbox>196)}197</>198)}199{copying == "starting" && (200<>201<Loading style={{ fontSize: "24px" }}>202Starting {project.title}...203</Loading>204</>205)}206{copying == "during" && (207<>208<Loading style={{ fontSize: "24px" }}>209Copying files to {project.title}...210</Loading>211</>212)}213{copying == "after" && (214<>215<Icon216name={errorCopying ? "times-circle" : "check"}217style={{ color: "darkgreen", fontSize: "16pt" }}218/>{" "}219Finished copying {targetPath} to{" "}220<A221href={editURL({222type: "collaborator",223project_id: project.project_id,224path: targetPath,225})}226external227>228{targetPath}229</A>{" "}230in your project{" "}231<A232href={editURL({233type: "collaborator",234project_id: project.project_id,235})}236external237>238{project.title}239</A>240.{" "}241{errorCopying ? (242<div>243<b>There appears to have been an issue copying files.</b>244</div>245) : (246""247)}248</>249)}250</div>251{errorCopying && (252<Alert type="warning" message={errorCopying} showIcon />253)}254{showListing && (255<div style={{ marginTop: "10px" }}>256<ProjectListing257project_id={project.project_id}258title={project.title}259path=""260update={copying}261sort="time"262/>263</div>264)}265</Space>266)}267</div>268);269}270271272