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/configuration/actions-panel.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Button, Card, Col, Row, Space } from "antd";6import { FormattedMessage, useIntl } from "react-intl";78import { useActions, useStore } from "@cocalc/frontend/app-framework";9import { Icon, Paragraph } from "@cocalc/frontend/components";10import { course } from "@cocalc/frontend/i18n";11import type { ProjectMap } from "@cocalc/frontend/todo-types";12import { RESEND_INVITE_INTERVAL_DAYS } from "@cocalc/util/consts/invites";13import { CourseActions } from "../actions";14import { CourseStore } from "../store";15import { DeleteAllStudentProjects } from "./delete-all-student-projects";16import { DeleteAllStudents } from "./delete-all-students";17import EmptyTrash from "./empty-trash";18import { StudentProjectsStartStopPanel } from "./start-stop-panel";19import { TerminalCommandPanel } from "./terminal-command";2021interface Props {22name: string;23project_map: ProjectMap;24configuring_projects?: boolean;25reinviting_students?: boolean;26}2728export function ActionsPanel({29name,30project_map,31configuring_projects,32reinviting_students,33}: Props) {34const actions = useActions<CourseActions>({ name });3536return (37<div className="smc-vfill" style={{ overflowY: "scroll" }}>38<Row>39<Col md={12} style={{ padding: "15px 15px 15px 0" }}>40<StartAllProjects name={name} project_map={project_map} />41<br />42<ReconfigureAllProjects43configuring_projects={configuring_projects}44actions={actions}45/>46<br />47<TerminalCommandPanel name={name} />48<br />49<ExportGrades actions={actions} />50</Col>51<Col md={12} style={{ padding: "15px" }}>52<ResendInvites53actions={actions}54reinviting_students={reinviting_students}55/>56<br />57<CopyMissingHandoutsAndAssignments actions={actions} />58<br />59<EmptyTrash />60<br />61<DeleteAllStudentProjects actions={actions} />62<br />63<DeleteAllStudents actions={actions} />64</Col>65</Row>66</div>67);68}6970export function StartAllProjects({ name, project_map }) {71const store = useStore<CourseStore>({ name });72const r = store.num_running_projects(project_map);73const n = store.num_students();74return (75<StudentProjectsStartStopPanel76name={name}77num_running_projects={r}78num_students={n}79/>80);81}8283export function ExportGrades({ actions, close }: { actions; close? }) {84const intl = useIntl();8586async function save_grades_to_csv() {87await actions.export.to_csv();88close?.();89}9091async function save_grades_to_py() {92await actions.export.to_py();93close?.();94}9596async function save_grades_to_json() {97await actions.export.to_json();98close?.();99}100101return (102<Card103title={104<>105<Icon name="table" /> {intl.formatMessage(course.export_grades)}106</>107}108>109<Paragraph style={{ marginBottom: "10px" }}>110<FormattedMessage111id="course.actions-panel.export-grades.title"112defaultMessage="Save grades to..."113/>114</Paragraph>115<Space>116<Button onClick={save_grades_to_csv}>117<Icon name="csv" /> CSV file...118</Button>119<Button onClick={save_grades_to_json}>120<Icon name="file-code" /> JSON file...121</Button>122<Button onClick={save_grades_to_py}>123<Icon name="file-code" /> Python file...124</Button>125</Space>126<hr />127<Paragraph type="secondary">128<FormattedMessage129id="course.actions-panel.export-grades.info"130defaultMessage={`Export all the grades you have recorded for students in your course131to a CSV or Python file.132{br}133In Microsoft Excel, you can <A>import the CSV file</A>.`}134values={{135A: (c) => (136<a137target="_blank"138href="https://support.microsoft.com/en-us/office/import-or-export-text-txt-or-csv-files-5250ac4c-663c-47ce-937b-339e391393ba?ui=en-us&rs=en-us&ad=us"139>140{c}141</a>142),143br: <br />,144}}145/>146</Paragraph>147</Card>148);149}150151export function ReconfigureAllProjects({152actions,153configuring_projects,154}: {155actions;156configuring_projects?: boolean;157}) {158const intl = useIntl();159160return (161<Card162title={163<>164<Icon name="envelope" />{" "}165{intl.formatMessage(course.reconfigure_all_projects)}166</>167}168>169<FormattedMessage170id="course.actions-panel.reconfigure-all-projects.info"171defaultMessage={`Ensure all projects have the correct students and TA's,172titles and descriptions set, etc.173This will also resend any outstanding email invitations.`}174/>175<hr />176<Button177disabled={configuring_projects}178onClick={() => {179actions.configuration.configure_all_projects();180}}181>182{configuring_projects ? <Icon name="cocalc-ring" spin /> : undefined}{" "}183{intl.formatMessage(course.reconfigure_all_projects)}184</Button>185</Card>186);187}188189export function ResendInvites({190actions,191reinviting_students,192}: {193actions;194reinviting_students?;195}) {196const intl = useIntl();197198return (199<Card200title={201<>202<Icon name="envelope" /> {intl.formatMessage(course.resend_invites)}203</>204}205>206<FormattedMessage207id="course.actions-panel.resend-invite.info"208defaultMessage={`Send another email to every student who didn't sign up yet.209This sends a maximum of one email every {days}210{days, plural, one {day} other {days}}.`}211values={{ days: RESEND_INVITE_INTERVAL_DAYS }}212/>213<hr />214<Button215disabled={reinviting_students}216onClick={() => {217actions.student_projects.reinvite_oustanding_students();218}}219>220{reinviting_students ? <Icon name="cocalc-ring" spin /> : undefined}{" "}221<FormattedMessage222id="course.actions-panel.resend-invite.button"223defaultMessage={"Reinvite students"}224description={"Resending email invitiatons to students in a course."}225/>226</Button>227</Card>228);229}230231export function CopyMissingHandoutsAndAssignments({ actions }) {232const intl = useIntl();233return (234<Card235title={236<>237<Icon name="share-square" />{" "}238{intl.formatMessage(course.copy_missing_handouts_assignments)}239</>240}241>242<FormattedMessage243id="course.actions-panel.copy-missing-handouts-assignments"244defaultMessage={`If you <b>add new students</b> to your course,245you can click this button to ensure they have all the assignments and handouts246that you have already assigned to other students in the course.`}247/>248<hr />249<Button250onClick={() => {251actions.configuration.push_missing_handouts_and_assignments();252}}253>254<Icon name="share-square" />{" "}255{intl.formatMessage(course.copy_missing_handouts_assignments)}256</Button>257</Card>258);259}260261262