Path: blob/master/src/packages/frontend/course/handouts/handouts-info-panel.tsx
1503 views
/*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 { CourseActions } from "../actions";17import { BigTime } from "../common";18import { LastCopyInfo } from "../store";1920interface StudentHandoutInfoProps {21actions: CourseActions;22info: { handout_id: string; student_id: string; status?: LastCopyInfo };23title: string;24}2526export function StudentHandoutInfo({27actions,28info,29title,30}: StudentHandoutInfoProps) {31const intl = useIntl();3233const [recopy, setRecopy] = useState<boolean>(false);3435function open(handout_id: string, student_id: string): void {36actions.handouts.open_handout(handout_id, student_id);37}3839function copy(handout_id: string, student_id: string): void {40actions.handouts.copy_handout_to_student(handout_id, student_id, false);41}4243function stop(handout_id: string, student_id: string): void {44actions.handouts.stop_copying_handout(handout_id, student_id);45}4647function render_last_time(time) {48return (49<div key="time" style={{ color: "#666" }}>50(<BigTime date={time} />)51</div>52);53}5455function render_open_recopy_confirm(name, copy, copy_tip) {56if (recopy) {57const v: any[] = [];58v.push(59<Button key="copy_cancel" onClick={() => setRecopy(false)}>60{intl.formatMessage(labels.cancel)}61</Button>,62);63v.push(64<Button65key="copy_confirm"66danger67onClick={() => {68setRecopy(false);69return copy();70}}71>72<Icon name="share-square" /> Yes, {name.toLowerCase()} again73</Button>,74);75return <Space wrap>{v}</Space>;76} else {77return (78<Button type="dashed" key="copy" onClick={() => setRecopy(true)}>79<Tip title={name} tip={<span>{copy_tip}</span>}>80<Icon name="share-square" /> {name}...81</Tip>82</Button>83);84}85}8687function render_open_recopy(name, open, copy, copy_tip, open_tip) {88return (89<Space key="open_recopy">90{render_open_recopy_confirm(name, copy, copy_tip)}91<Button key="open" onClick={open}>92<Tip title="Open Folder" tip={open_tip}>93<Icon name="folder-open" /> Open directory...94</Tip>95</Button>96</Space>97);98}99100function render_open_copying(open, stop) {101return (102<Space key="open_copying">103<Button key="copy" type="primary" disabled={true}>104<Icon name="cocalc-ring" spin /> Working...105</Button>106<Button key="stop" danger onClick={stop}>107<Icon name="times" />108</Button>109<Button key="open" onClick={open}>110<Icon name="folder-open" /> Open111</Button>112</Space>113);114}115116function render_copy(name, copy, copy_tip) {117return (118<Tip key="copy" title={name} tip={copy_tip}>119<Button onClick={copy} type="primary">120<Icon name="share-square" /> {name}121</Button>122</Tip>123);124}125126function render_error(name, error) {127if (typeof error !== "string") {128error = `${error}`;129}130if (error.includes("[object Object]")) {131// already too late to know the actual error -- it got mangled/reported incorrectly132error = "";133}134if (error.indexOf("No such file or directory") !== -1) {135error = `Somebody may have moved the folder that should have contained the handout -- \n${error}`;136} else {137error = `Try to ${name.toLowerCase()} again -- \n${error}`;138}139return (140<ShowError141key="error"142error={error}143style={{ marginTop: "5px", maxHeight: "140px", overflow: "auto" }}144/>145);146}147148function render_last(name, obj, info, enable_copy, copy_tip, open_tip) {149const do_open = () => open(info.handout_id, info.student_id);150const do_copy = () => copy(info.handout_id, info.student_id);151const do_stop = () => stop(info.handout_id, info.student_id);152if (obj == null) {153obj = {};154}155const v: any[] = [];156if (enable_copy) {157if (webapp_client.server_time() - (obj.start ?? 0) < COPY_TIMEOUT_MS) {158v.push(render_open_copying(do_open, do_stop));159} else if (obj.time) {160v.push(render_open_recopy(name, do_open, do_copy, copy_tip, open_tip));161} else {162v.push(render_copy(name, do_copy, copy_tip));163}164}165if (obj.time) {166v.push(render_last_time(obj.time));167}168if (obj.error) {169v.push(render_error(name, obj.error));170}171return v;172}173174return (175<div>176<Row177style={{178borderTop: "1px solid #aaa",179paddingTop: "5px",180paddingBottom: "5px",181}}182>183<Col md={4} key="title">184{title}185</Col>186<Col md={20} key="rest">187<Row>188<Col md={24} key="last_handout">189{render_last(190"Distribute",191info.status,192info,193true,194"Copy the handout from your project to this student's project.",195"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.",196)}197</Col>198</Row>199</Col>200</Row>201</div>202);203}204205206