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/frontend/compute/detailed-state.tsx
Views: 687
import { Progress, Tooltip } from "antd";1import { Icon, TimeAgo } from "@cocalc/frontend/components";2import { capitalize } from "@cocalc/util/misc";3import { DisplayImage } from "./select-image";4import ShowError from "@cocalc/frontend/components/error";5import { setDetailedState } from "./api";6import SyncButton from "./sync-button";78const SPEC = {9compute: {10icon: "server",11label: "Compute",12tip: "Jupyter kernel and terminal software environment",13},14filesystem: {15icon: "files",16label: "Filesystem",17tip: "Service that manages mounting and syncing the /home/user filesystem",18},19"filesystem-sync": {20icon: "sync",21label: "Sync",22// no tip on purpose since button provides tip23},24"filesystem-cache": {25icon: "disk-round",26label: "Cache",27tip: "Cache frequently read files from project on compute server",28},29"filesystem-network": {30icon: "network-wired",31label: "Mount",32tip: "Network mounted /home/user filesystem",33},34vm: {35icon: "desktop",36label: "Virtual Machine",37tip: "Underlying virtual machine on which the compute server containers are running",38},39install: {40icon: "cloud-dev",41label: "Install",42tip: "Install Docker, Nodejs, and CoCalc software on the compute server",43},44};4546// order the components47const COMPONENTS = [48"filesystem-sync",49"compute",50"vm",51"filesystem",52"filesystem-cache",53"filesystem-network",54"install",55];5657export default function DetailedState({58id,59project_id,60detailed_state,61color,62configuration,63}) {64if (!detailed_state) {65return null;66}67const v: JSX.Element[] = [];68for (const name of COMPONENTS) {69if (detailed_state[name]) {70v.push(71<State72id={id}73project_id={project_id}74key={name}75name={name}76configuration={configuration}77{...detailed_state[name]}78/>,79);80}81}82for (const name in detailed_state) {83if (!COMPONENTS.includes(name)) {84v.push(85<State86id={id}87project_id={project_id}88key={name}89name={name}90configuration={configuration}91{...detailed_state[name]}92/>,93);94}95}96return (97<div style={{ borderTop: `1px solid ${color}`, marginTop: "10px" }}>98{v}99</div>100);101}102103function toLabel(name: string) {104if (!name) return "";105return name106.split("-")107.map((x) => capitalize(x))108.join(" ");109}110111function State({112name,113state,114time,115expire,116progress,117extra,118configuration,119project_id,120id,121}) {122const expired = expire && expire < Date.now();123let label;124if (name == "filesystem-sync") {125let disabled = false;126if (configuration?.excludeFromSync != null) {127if (128configuration.excludeFromSync.includes("~") ||129configuration.excludeFromSync.includes(".")130) {131disabled = true;132}133}134label = (135<SyncButton136disabled={disabled}137size="small"138compute_server_id={id}139project_id={project_id}140time={time}141syncing={142!extra &&143progress <14480 /* 80 because the last per for read cache is not sync and sometimes gets stuck */145}146/>147);148} else if (name == "compute") {149label = <DisplayImage configuration={configuration} />;150} else if (SPEC[name]?.label) {151label = SPEC[name].label;152} else {153label = toLabel(name);154}155156return (157<div158style={{159borderBottom: "1px solid #ddd",160height: "24px",161overflow: "hidden",162whiteSpace: "nowrap",163}}164>165<div style={{ display: "flex" }}>166<Tooltip title={SPEC[name]?.tip}>167<div168style={{169flex: 1,170color: expired ? "#aaa" : undefined,171}}172>173{name != "compute" && name != "filesystem-sync" && (174<>175<Icon176name={SPEC[name]?.icon ?? "cube"}177style={{ marginRight: "5px" }}178/>{" "}179</>180)}181{label}182</div>183</Tooltip>184{!expired && (185<>186<div style={{ flex: 1 }}>187{!expired && <Progress percent={progress ?? 0} size="small" />}188</div>189<div style={{ flex: 1, textAlign: "center" }}>190{state == "ready" ? (191"Ready"192) : (193<Tooltip title={toLabel(state)}>194<Icon name="run" />195</Tooltip>196)}197</div>198<div199style={{200flex: 1,201textAlign: "center",202height: "30px",203overflow: "auto",204}}205>206{/* only show time when at least a minute in past to avoid annoying flicker */}207{(time ?? 0) < Date.now() - 60 * 1000 && <TimeAgo date={time} />}208</div>209</>210)}211</div>212{extra && (213<div214style={{215display: "flex",216}}217>218<div style={{ flex: 0.1 }} />219<div style={{ flex: 0.9 }}>220{state == "error" ? (221<ShowError222style={{223marginBottom: "10px",224position: "absolute",225maxWidth: "400px",226zIndex: 1,227}}228error={extra}229setError={() => {230setDetailedState({231id,232project_id,233name,234extra: "",235state: "ready",236});237}}238/>239) : (240extra241)}242</div>243</div>244)}245</div>246);247}248249250