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/project/create.tsx
Views: 687
/* Create a new project.1*/23import { useState } from "react";4import { Alert, Button, Divider, Input, Space } from "antd";5import Loading from "components/share/loading";6import A from "components/misc/A";7import { Icon } from "@cocalc/frontend/components/icon";8import apiPost from "lib/api/post";9import editURL from "lib/share/edit-url";1011interface Props {12label?: string;13image?: string; // optional compute image14defaultTitle?: string;15start?: boolean; // start as soon as it is created.16onCreate: (project: { project_id: string; title: string }) => void;17public_path_id?: string; // if given, project is being created in order to use this public path, so a license might be applied.18}1920export default function CreateProject({21label,22image,23defaultTitle,24start,25onCreate,26public_path_id,27}: Props) {28const [title, setTitle] = useState<string>(defaultTitle ?? "");29const [project_id, setProjectID] = useState<string>("");30const [error, setError] = useState<string>("");31const [state, setState] = useState<32"config" | "creating" | "starting" | "created"33>("config");3435async function create(title: string) {36setError("");37setState("creating");38try {39const response = await apiPost("/projects/create", {40title,41image,42public_path_id,43});44if (response.error) {45throw Error(response.error);46}47if (start) {48setState("starting");49await apiPost("/projects/start", { project_id: response.project_id });50}51setProjectID(response.project_id);52setState("created");53onCreate({ project_id: response.project_id, title });54} catch (err) {55setState("config");56setError(`${err}`);57}58}5960return (61<div>62<Divider style={{ color: "#666" }}>{label ?? "Create a Project"}</Divider>63<Space direction="vertical" style={{ width: "100%" }}>64{error && <Alert type="error" message={error} showIcon />}65{state == "creating" && (66<div style={{ textAlign: "center" }}>67<Loading style={{ fontSize: "16pt" }}>68Creating project "{title}"...69</Loading>70</div>71)}72{state == "starting" && (73<div style={{ textAlign: "center" }}>74<Loading style={{ fontSize: "16pt" }}>75Starting project "{title}"...76</Loading>77</div>78)}79{state == "created" && (80<div>81<Icon82name="check"83style={{ color: "darkgreen", fontSize: "16pt" }}84/>{" "}85Created project{" "}86{project_id && title ? (87<A88href={editURL({89type: "collaborator",90project_id,91})}92external93>94{title}95</A>96) : (97""98)}99.100</div>101)}102<Input103allowClear104defaultValue={defaultTitle}105disabled={state != "config"}106placeholder="Project title (easily change this at any time)"107onChange={(e) => setTitle(e.target.value)}108onPressEnter={(e) => {109e.preventDefault();110create(title);111}}112/>113{state == "config" && (114<Button115disabled={!title || state != "config"}116type={title ? "primary" : undefined}117onClick={() => create(title)}118>119<Icon name="plus-circle" /> Create New Project120</Button>121)}122</Space>123</div>124);125}126127128