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/course/handouts/handouts-info-panel.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45// CoCalc libraries6// React Libraries7import { Button, Col, Row, Space } from "antd";8import { useState } from "react";9import { useIntl } from "react-intl";1011import { Icon, Tip } from "@cocalc/frontend/components";12import ShowError from "@cocalc/frontend/components/error";13import { COPY_TIMEOUT_MS } from "@cocalc/frontend/course/consts";14import { labels } from "@cocalc/frontend/i18n";15import { webapp_client } from "@cocalc/frontend/webapp-client";16import { to_json } from "@cocalc/util/misc";17import { CourseActions } from "../actions";18import { BigTime } from "../common";19import { LastCopyInfo } from "../store";2021interface StudentHandoutInfoProps {22actions: CourseActions;23info: { handout_id: string; student_id: string; status?: LastCopyInfo };24title: string;25}2627export function StudentHandoutInfo({28actions,29info,30title,31}: StudentHandoutInfoProps) {32const intl = useIntl();3334const [recopy, setRecopy] = useState<boolean>(false);3536function open(handout_id: string, student_id: string): void {37actions.handouts.open_handout(handout_id, student_id);38}3940function copy(handout_id: string, student_id: string): void {41actions.handouts.copy_handout_to_student(handout_id, student_id, false);42}4344function stop(handout_id: string, student_id: string): void {45actions.handouts.stop_copying_handout(handout_id, student_id);46}4748function render_last_time(time) {49return (50<div key="time" style={{ color: "#666" }}>51(<BigTime date={time} />)52</div>53);54}5556function render_open_recopy_confirm(name, copy, copy_tip) {57if (recopy) {58const v: any[] = [];59v.push(60<Button key="copy_cancel" onClick={() => setRecopy(false)}>61{intl.formatMessage(labels.cancel)}62</Button>,63);64v.push(65<Button66key="copy_confirm"67danger68onClick={() => {69setRecopy(false);70return copy();71}}72>73<Icon name="share-square" /> Yes, {name.toLowerCase()} again74</Button>,75);76return <Space wrap>{v}</Space>;77} else {78return (79<Button type="dashed" key="copy" onClick={() => setRecopy(true)}>80<Tip title={name} tip={<span>{copy_tip}</span>}>81<Icon name="share-square" /> {name}...82</Tip>83</Button>84);85}86}8788function render_open_recopy(name, open, copy, copy_tip, open_tip) {89return (90<Space key="open_recopy">91{render_open_recopy_confirm(name, copy, copy_tip)}92<Button key="open" onClick={open}>93<Tip title="Open Folder" tip={open_tip}>94<Icon name="folder-open" /> Open directory...95</Tip>96</Button>97</Space>98);99}100101function render_open_copying(open, stop) {102return (103<Space key="open_copying">104<Button key="copy" type="primary" disabled={true}>105<Icon name="cocalc-ring" spin /> Working...106</Button>107<Button key="stop" danger onClick={stop}>108<Icon name="times" />109</Button>110<Button key="open" onClick={open}>111<Icon name="folder-open" /> Open112</Button>113</Space>114);115}116117function render_copy(name, copy, copy_tip) {118return (119<Tip key="copy" title={name} tip={copy_tip}>120<Button onClick={copy} type="primary">121<Icon name="share-square" /> {name}122</Button>123</Tip>124);125}126127function render_error(name, error) {128if (typeof error !== "string") {129error = to_json(error);130}131if (error.indexOf("No such file or directory") !== -1) {132error = `Somebody may have moved the folder that should have contained the handout.\n${error}`;133} else {134error = `Try to ${name.toLowerCase()} again:\n` + error;135}136return (137<ShowError138key="error"139error={error}140style={{ marginTop: "5px", maxHeight: "140px", overflow: "auto" }}141/>142);143}144145function render_last(name, obj, info, enable_copy, copy_tip, open_tip) {146const do_open = () => open(info.handout_id, info.student_id);147const do_copy = () => copy(info.handout_id, info.student_id);148const do_stop = () => stop(info.handout_id, info.student_id);149if (obj == null) {150obj = {};151}152const v: any[] = [];153if (enable_copy) {154if (webapp_client.server_time() - (obj.start ?? 0) < COPY_TIMEOUT_MS) {155v.push(render_open_copying(do_open, do_stop));156} else if (obj.time) {157v.push(render_open_recopy(name, do_open, do_copy, copy_tip, open_tip));158} else {159v.push(render_copy(name, do_copy, copy_tip));160}161}162if (obj.time) {163v.push(render_last_time(obj.time));164}165if (obj.error) {166v.push(render_error(name, obj.error));167}168return v;169}170171return (172<div>173<Row174style={{175borderTop: "1px solid #aaa",176paddingTop: "5px",177paddingBottom: "5px",178}}179>180<Col md={4} key="title">181{title}182</Col>183<Col md={20} key="rest">184<Row>185<Col md={24} key="last_handout">186{render_last(187"Distribute",188info.status,189info,190true,191"Copy the handout from your project to this student's project.",192"Open the student's copy of this handout directly in their project. You will be able to see them type, chat with them, answer questions, etc.",193)}194</Col>195</Row>196</Col>197</Row>198</div>199);200}201202203