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/assignments/configure-peer.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Panel for configuring peer grading.7*/89import {10DateTimePicker,11Icon,12MarkdownInput,13} from "@cocalc/frontend/components";14import { server_days_ago } from "@cocalc/util/misc";15import { Button, Card, Col, InputNumber, Row, Switch, Typography } from "antd";16import { CourseActions } from "../actions";17import { AssignmentRecord } from "../store";18import {19PEER_GRADING_GUIDE_FILENAME,20PEER_GRADING_GUIDELINES_GRADE_MARKER,21PEER_GRADING_DEFAULT_GUIDELINES,22} from "./consts";2324interface Props {25assignment: AssignmentRecord;26actions: CourseActions;27}2829export function ConfigurePeerGrading({ assignment, actions }: Props) {30const peer_info = assignment.get("peer_grade");31const config: { enabled: boolean; number: number } = {32number: 1,33enabled: false,34...peer_info?.toJS(),35};3637function render_configure_peer_checkbox(config) {38return (39<Row style={{ marginTop: "10px" }}>40<Col span={12}>41<Switch42checked={config.enabled}43onChange={(checked) => set_peer_grade({ enabled: checked })}44style={{ display: "inline-block", verticalAlign: "middle" }}45/>46</Col>47<Col span={12}>Enable Peer Grading</Col>48</Row>49);50}5152function peer_due(date): Date | undefined {53if (date != null) {54return new Date(date);55} else {56return server_days_ago(-7);57}58}5960function set_peer_grade(config) {61if (config.enabled && !config.guidelines?.trim()) {62config.guidelines = PEER_GRADING_DEFAULT_GUIDELINES;63}64actions.assignments.set_peer_grade(assignment.get("assignment_id"), config);65}6667function peer_due_change(date) {68const due_date = peer_due(date);69set_peer_grade({70due_date: due_date?.toISOString(),71});72}7374function render_configure_peer_due(config) {75const label = (76<Typography.Paragraph77ellipsis={{ expandable: true, rows: 1, symbol: "more info" }}78>79Due date:{" "}80<Typography.Text type={"secondary"}>81Set the due date for grading this assignment. Note: you must82explicitly click a button to collect graded assignments – they are not83automatically collected on the due date. A file is included in the84student peer grading assignment telling them when they should finish85their grading.86</Typography.Text>87</Typography.Paragraph>88);89return (90<Row style={{ marginTop: "10px" }}>91<Col span={12}>{label}</Col>92<Col span={12}>93<DateTimePicker94style={{ width: "100%" }}95placeholder={"Set Peer Grading Due Date"}96value={peer_due(config.due_date)}97onChange={peer_due_change}98/>99</Col>100</Row>101);102}103104function render_configure_peer_number(config) {105const store = actions.get_store();106const maxVal = (store?.num_students() ?? 2) - 1;107return (108<Row style={{ marginTop: "10px" }}>109<Col span={12}>Number of students who will grade each assignment</Col>110<Col span={12}>111<InputNumber112onChange={(n) => set_peer_grade({ number: n })}113min={1}114max={maxVal}115value={config.number}116/>117</Col>118</Row>119);120}121122function render_configure_grading_guidelines(config) {123return (124<Row style={{ marginTop: "10px" }}>125<Col span={12}>126<Typography.Paragraph127ellipsis={{ expandable: true, rows: 1, symbol: "more info" }}128>129Grading guidelines:{" "}130<Typography.Text type={"secondary"}>131This text will be made available to students in their grading132folder in a file <code>{PEER_GRADING_GUIDE_FILENAME}</code>. Tell133your students how to grade each problem. Since this is a markdown134file, you might also provide a link to a publicly shared file or135directory with additional guidelines. If you keep the default "136{PEER_GRADING_GUIDELINES_GRADE_MARKER}" text, then the grade the137student puts after that will be parsed from the file and the138default grade assigned to the student will be the average of the139peer grades. You can edit the grade before returning the graded140assignment to the student.141</Typography.Text>142</Typography.Paragraph>143</Col>144<Col span={12}>145<div146style={{147background: "white",148padding: "10px",149border: "1px solid #ccc",150borderRadius: "3px",151}}152>153<MarkdownInput154persist_id={155assignment.get("path") +156assignment.get("assignment_id") +157"grading-guidelines"158}159attach_to={actions.name}160rows={16}161placeholder="Enter your grading guidelines for this assignment..."162default_value={config.guidelines}163on_save={(x) => set_peer_grade({ guidelines: x })}164/>165</div>166</Col>167</Row>168);169}170171function render_configure_grid(config) {172return (173<>174{render_configure_peer_number(config)}175{render_configure_peer_due(config)}176{render_configure_grading_guidelines(config)}177</>178);179}180181return (182<Card183style={{ background: "#fcf8e3", whiteSpace: "normal" }}184title={185<h3>186<Icon name="users" /> Peer grading187</h3>188}189>190<Typography.Text type="secondary">191Use peer grading to randomly (and anonymously) redistribute collected192homework to your students, so that they can grade it for you.193</Typography.Text>194195{render_configure_peer_checkbox(config)}196{config.enabled ? render_configure_grid(config) : undefined}197<div style={{ marginTop: "10px" }}>198<Button199onClick={() =>200actions.toggle_item_expansion(201"peer_config",202assignment.get("assignment_id"),203)204}205>206Close207</Button>208</div>209</Card>210);211}212213214