Path: blob/master/src/packages/frontend/course/common/course-unit-strings.tsx
10799 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { ReactNode } from "react";6import type { IntlShape } from "react-intl";78import { labels } from "@cocalc/frontend/i18n";910import type { AssignmentCopyStep, AssignmentStep } from "../types";1112export type UnitLabel = "assignment" | "handout";1314interface ControlMessages {15label: string;16title: string;17tip: string;18}1920interface DeleteConfirmMessages {21title: string;22body: string;23}2425interface NoContentMessages {26message: string;27description: (openDirLink: (chunks: ReactNode) => ReactNode) => ReactNode;28}2930export function openFolderMessages(31intl: IntlShape,32unitLabel: UnitLabel,33): ControlMessages {34return {35label: intl.formatMessage(labels.open),36title: intl.formatMessage({37id: "course.unit_strings.open_folder.title",38defaultMessage: "Open Folder",39}),40tip:41unitLabel === "assignment"42? intl.formatMessage({43id: "course.unit_strings.open_folder.tip.assignment",44defaultMessage:45"Open the directory in the current project that contains the original files for this assignment. Edit files in this folder to create the content that your students will see when they receive this assignment.",46})47: intl.formatMessage({48id: "course.unit_strings.open_folder.tip.handout",49defaultMessage:50"Open the directory in the current project that contains the original files for this handout. Edit files in this folder to create the content that your students will see when they receive this handout.",51}),52};53}5455export function fileActivityMessages(56intl: IntlShape,57unitLabel: UnitLabel,58): ControlMessages {59return {60label: intl.formatMessage({61id: "course.unit_strings.file_activity.label",62defaultMessage: "File Activity",63}),64title: intl.formatMessage({65id: "course.unit_strings.file_activity.title",66defaultMessage: "Export File Activity Data",67}),68tip: intl.formatMessage(69{70id: "course.unit_strings.file_activity.tip",71defaultMessage:72"Export a JSON file containing detailed information about when students have opened or edited files in this {unitLabel, select, assignment {assignment} other {handout}}. The JSON file opens in a new tab; {accessField} (milliseconds since the UNIX epoch) indicate when files were opened, and {editField} indicate when they were changed in CoCalc's web editor.",73description:74"{accessField} and {editField} are literal JSON field names and should not be translated. {unitLabel} is 'assignment' or 'handout'.",75},76{77unitLabel,78accessField: "access_times",79editField: "edit_times",80},81),82};83}8485export function exportCollectedMessages(intl: IntlShape): ControlMessages {86return {87label: intl.formatMessage({88id: "course.unit_strings.export.label",89defaultMessage: "Export",90description:91"Button label in assignment header; exports collected student files as a zip archive",92}),93title: intl.formatMessage({94id: "course.unit_strings.export_collected.title",95defaultMessage: "Export Collected Files",96}),97tip: intl.formatMessage({98id: "course.unit_strings.export_collected.tip",99defaultMessage:100"Export a zip file containing all collected student assignments. This may take a while for large classes.",101}),102};103}104105export function undeleteMessages(106intl: IntlShape,107unitLabel: UnitLabel,108): ControlMessages {109return {110label: intl.formatMessage({111id: "course.unit_strings.undelete.label",112defaultMessage: "Undelete",113description:114"Button label in course unit header; restores a previously deleted assignment or handout",115}),116title:117unitLabel === "assignment"118? intl.formatMessage({119id: "course.unit_strings.undelete.title.assignment",120defaultMessage: "Undelete Assignment",121})122: intl.formatMessage({123id: "course.unit_strings.undelete.title.handout",124defaultMessage: "Undelete Handout",125}),126tip:127unitLabel === "assignment"128? intl.formatMessage({129id: "course.unit_strings.undelete.tip.assignment",130defaultMessage:131"Make the assignment visible again in the assignment list and in student grade lists.",132})133: intl.formatMessage({134id: "course.unit_strings.undelete.tip.handout",135defaultMessage:136"Make the handout visible again in the handout list.",137}),138};139}140141export function deleteConfirmMessages(142intl: IntlShape,143unitLabel: UnitLabel,144path: string,145): DeleteConfirmMessages {146return {147title: intl.formatMessage(148{149id: "course.unit_strings.delete_confirm.title",150defaultMessage: 'Are you sure you want to delete "{path}"?',151},152{ path },153),154body:155unitLabel === "assignment"156? intl.formatMessage({157id: "course.unit_strings.delete_confirm.body.assignment",158defaultMessage:159'This removes it from the assignment list and student grade lists, but does not delete any files from disk. You can always undelete it later by clicking "Show deleted assignments".',160})161: intl.formatMessage({162id: "course.unit_strings.delete_confirm.body.handout",163defaultMessage:164'This removes it from the handout list, but does not delete any files from disk. You can always undelete it later by clicking "Show deleted handouts".',165}),166};167}168169export function deleteLabel(intl: IntlShape): string {170return intl.formatMessage({171id: "course.unit_strings.delete.label",172defaultMessage: "Delete...",173description:174"Button label in course unit header; opens confirmation to remove assignment or handout from the list",175});176}177178export function dueDateMessages(intl: IntlShape): ControlMessages {179return {180label: intl.formatMessage({181id: "course.unit_strings.due.label",182defaultMessage: "Due:",183description:184"Inline label before the due date/time picker in unit header",185}),186title: intl.formatMessage({187id: "course.unit_strings.due_date.title",188defaultMessage: "Due Date",189description: "Tooltip title for the due date/time picker in unit header",190}),191tip: intl.formatMessage(192{193id: "course.unit_strings.due_date.tip",194defaultMessage:195"Set the due date for this assignment. This changes how assignments are sorted. Assignments are not automatically collected when due; you must collect them explicitly. CoCalc also writes the due date to {dueDateFile} in the assignment folder.",196description:197"{dueDateFile} is a literal filename and should not be translated",198},199{ dueDateFile: "DUE_DATE.txt" },200),201};202}203204export function skipStepMessages(intl: IntlShape): ControlMessages {205return {206label: intl.formatMessage({207id: "course.unit_strings.skip_step.label",208defaultMessage: "Skip",209description: "Short label shown on the skip toggle in step headers",210}),211title: intl.formatMessage({212id: "course.unit_strings.skip_step.title",213defaultMessage: "Skip This Step",214description: "Tooltip title for the skip toggle in step headers",215}),216tip: intl.formatMessage({217id: "course.unit_strings.skip_step.tip",218defaultMessage:219"Toggle to allow proceeding to the next step without completing this one.",220}),221};222}223224export function filterPlaceholder(intl: IntlShape): string {225return intl.formatMessage({226id: "course.unit_strings.filter_students.placeholder",227defaultMessage: "Filter students...",228description:229"Placeholder text in input used to filter the student list by name",230});231}232233export function noteMessages(intl: IntlShape, unitLabel: UnitLabel) {234return {235title:236unitLabel === "assignment"237? intl.formatMessage({238id: "course.assignments.assignment_notes.tooltip.title",239defaultMessage: "Notes about this assignment",240})241: intl.formatMessage({242id: "course.handouts.handout_notes.tooltip.title",243defaultMessage: "Notes about this handout",244}),245tip:246unitLabel === "assignment"247? intl.formatMessage({248id: "course.assignments.assignment_notes.tooltip.tooltip",249defaultMessage: `Record notes about this assignment here.250These notes are only visible to you, not to your students.251Put any instructions to students about assignments in a file in the directory252that contains the assignment.`,253})254: intl.formatMessage({255id: "course.handouts.handout_notes.tooltip.tooltip",256defaultMessage: `Record notes about this handout here.257These notes are only visible to you, not to your students.258Put any instructions to students about handouts in a file in the directory259that contains the handout.`,260}),261placeholder:262unitLabel === "assignment"263? intl.formatMessage({264id: "course.assignments.assignment_notes.placeholder",265defaultMessage:266"Private notes about this assignment (not visible to students)",267})268: intl.formatMessage({269id: "course.handouts.handout_notes.placeholder",270defaultMessage:271"Private notes about this handout (not visible to students)",272}),273};274}275276export function noContentMessages(277intl: IntlShape,278unitLabel: UnitLabel,279): NoContentMessages {280return {281message:282unitLabel === "assignment"283? intl.formatMessage({284id: "course.unit_strings.no_content.message.assignment",285defaultMessage: "No files in this assignment yet",286description:287"Warning message in assignment card when assignment directory has no files",288})289: intl.formatMessage({290id: "course.unit_strings.no_content.message.handout",291defaultMessage: "No files in this handout yet",292description:293"Warning message in handout card when handout directory has no files",294}),295description: (openDirLink) =>296unitLabel === "assignment"297? intl.formatMessage(298{299id: "course.unit_strings.no_content.description.assignment",300defaultMessage:301"Please <openDirLink>open the directory</openDirLink> for this assignment, then create, upload, or copy any content you want into that directory. You will then be able to send it to all of your students.",302description:303"Warning description in assignment card when assignment directory has no files",304},305{ openDirLink },306)307: intl.formatMessage(308{309id: "course.unit_strings.no_content.description.handout",310defaultMessage:311"Please <openDirLink>open the directory</openDirLink> for this handout, then create, upload, or copy any content you want into that directory. You will then be able to send it to all of your students.",312description:313"Warning description in handout card when handout directory has no files",314},315{ openDirLink },316),317};318}319320export function runAllAriaLabel(intl: IntlShape, step: AssignmentStep): string {321switch (step) {322case "assignment":323return intl.formatMessage({324id: "course.run_all.aria.assignment",325defaultMessage: "Assign to all students options",326});327case "collect":328return intl.formatMessage({329id: "course.run_all.aria.collect",330defaultMessage: "Collect from all students options",331});332case "peer_assignment":333return intl.formatMessage({334id: "course.run_all.aria.peer_assignment",335defaultMessage: "Assign for peer grading options",336});337case "peer_collect":338return intl.formatMessage({339id: "course.run_all.aria.peer_collect",340defaultMessage: "Collect peer feedback options",341});342case "return_graded":343return intl.formatMessage({344id: "course.run_all.aria.return_graded",345defaultMessage: "Return to all students options",346});347case "grade":348return intl.formatMessage({349id: "course.run_all.aria.grade",350defaultMessage: "Autograde options",351});352case "distribution":353return intl.formatMessage({354id: "course.run_all.aria.distribution",355defaultMessage: "Distribute to all students options",356});357default:358return intl.formatMessage({359id: "course.run_all.aria.default",360defaultMessage: "Run all options",361});362}363}364365export function peerGradingMessages(intl: IntlShape) {366return {367label: intl.formatMessage({368id: "course.unit_strings.peer_grading.label",369defaultMessage: "Peer Grading...",370description: "Button label in assignment header to configure peer grading",371}),372disabledTooltip: intl.formatMessage(373{374id: "course.unit_strings.peer_disabled.tooltip",375defaultMessage:376"Peer grading is disabled because {pkg} notebooks were detected",377description: "{pkg} is a package name and should not be translated",378},379{ pkg: "nbgrader" },380),381disabledAlert: intl.formatMessage(382{383id: "course.unit_strings.peer_disabled.alert",384defaultMessage:385"Peer grading was disabled because {pkg} notebooks were detected. Remove {pkg} metadata to re-enable peer grading.",386description: "{pkg} is a package name and should not be translated",387},388{ pkg: "nbgrader" },389),390};391}392393export function copyConfirmAllCaution(394intl: IntlShape,395step: AssignmentCopyStep,396): ReactNode {397switch (step) {398case "assignment":399return intl.formatMessage(400{401id: "course.unit_strings.copy_confirm_all.assignment",402defaultMessage:403'CAUTION: All files will be copied again. If you updated a file that a student has also worked on, it will get copied to a backup file ending in a tilde (~), or possibly only be available in snapshots. Select "Replace student files!" if you do <b>not</b> want to create any backups and want to <b>delete</b> all other files in the assignment folder of student projects. <detailsLink>Details</detailsLink>',404description:405"Warning shown before recopying assignment files for all students",406},407{408b: (chunks) => <b>{chunks}</b>,409detailsLink: (chunks) => (410<a411rel="noopener noreferrer"412target="_blank"413href="https://doc.cocalc.com/teaching-tips_and_tricks.html#how-exactly-are-assignments-copied-to-students"414>415{chunks}416</a>417),418},419);420case "collect":421case "peer_collect":422return intl.formatMessage({423id: "course.unit_strings.copy_confirm_all.collect",424defaultMessage:425"CAUTION: All files will be copied again. If you have graded or edited a file that a student has updated, it will get copied to a backup file ending in a tilde (~), or possibly only be available in snapshots.",426});427case "peer_assignment":428return intl.formatMessage({429id: "course.unit_strings.copy_confirm_all.peer_assignment",430defaultMessage:431"CAUTION: All files will be copied again. If a student worked on a previously assigned file, it will get copied to a backup file ending in a tilde (~), or possibly only be available in snapshots.",432});433case "return_graded":434return intl.formatMessage({435id: "course.unit_strings.copy_confirm_all.return_graded",436defaultMessage:437"CAUTION: All files will be copied again. If a student edited a previously returned file, it will get copied to a backup file ending in a tilde (~), or possibly only be available in snapshots.",438});439}440}441442export function handoutCopyConfirmAllCaution(intl: IntlShape): string {443return intl.formatMessage({444id: "course.unit_strings.copy_confirm_all.handout",445defaultMessage:446'This will copy all files to all students again. CAUTION: if you update a file that a student has also worked on, their work will get copied to a backup file ending in a tilde, or possibly only be available in snapshots. Select "Replace student files!" if you do not want to create any backups and also delete all other files in the handout directory of their projects.',447});448}449450export function nbgraderMessages(intl: IntlShape) {451return {452intro: intl.formatMessage(453{454id: "course.unit_strings.nbgrader_run_all.intro",455defaultMessage: "Autograde this assignment using {pkg} for",456description:457"{pkg} is a package name and should not be translated. This phrase is followed by a button label like 'The 5 students not yet autograded'.",458},459{460pkg: "nbgrader",461},462),463remainingButton: (todo: number) =>464intl.formatMessage(465{466id: "course.unit_strings.nbgrader_run_all.remaining",467defaultMessage:468"The {count, plural, one {# student not yet autograded} other {# students not yet autograded}}",469},470{ count: todo },471),472allButton: (total: number) =>473intl.formatMessage(474{475id: "course.unit_strings.nbgrader_run_all.all_button",476defaultMessage:477"All {count, plural, one {# student} other {# students}}...",478},479{ count: total },480),481confirmAllPrompt: (total: number) =>482intl.formatMessage(483{484id: "course.unit_strings.nbgrader_run_all.confirm_prompt",485defaultMessage:486"Are you sure you want to autograde ALL {count, plural, one {# student} other {# students}}?",487},488{ count: total },489),490confirmAllAction: (total: number) =>491intl.formatMessage(492{493id: "course.unit_strings.nbgrader_run_all.confirm_action",494defaultMessage:495"Autograde all {count, plural, one {# student} other {# students}}",496},497{ count: total },498),499syncButton: intl.formatMessage({500id: "course.unit_strings.nbgrader_run_all.sync_button",501defaultMessage: "Sync grades...",502description:503"Button label in nbgrader run-all popover; opens confirmation to sync nbgrader scores into assigned grades for all students",504}),505syncPrompt: intl.formatMessage(506{507id: "course.unit_strings.nbgrader_run_all.sync_prompt",508defaultMessage:509"Force-sync {pkg} scores to assigned grades for all students, including submissions with ungraded manual items or errors?",510description: "{pkg} is a package name and should not be translated",511},512{513pkg: "nbgrader",514},515),516syncAction: intl.formatMessage({517id: "course.unit_strings.nbgrader_run_all.sync_action",518defaultMessage: "Sync grades for all students",519}),520back: intl.formatMessage({521id: "course.unit_strings.nbgrader_run_all.back",522defaultMessage: "Back",523description:524"Button label in nbgrader run-all popover; returns from confirmation view to previous options",525}),526};527}528529530