Path: blob/master/src/packages/frontend/course/common/handout-header.tsx
10799 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Input } from "antd";6import { useEffect, useState } from "react";7import { DebounceInput } from "react-debounce-input";8import { useIntl } from "react-intl";910import { CourseActions } from "../actions";11import type { HandoutRecord } from "../store";12import { CopyRunAllAlert } from "./copy-run-all";13import { filterPlaceholder, runAllAriaLabel } from "./course-unit-strings";14import type { HandoutStatus } from "./course-unit-types";15import { Progress } from "./progress";16import { RunAllPopover } from "./run-all-popover";17import { StudentAssignmentInfoHeader } from "./student-assignment-info-header";1819interface HandoutHeaderProps {20handout: HandoutRecord;21status: HandoutStatus | null;22numStudents: number;23actions: CourseActions;24studentSearch: string;25setStudentSearch: (value: string) => void;26}2728export function HandoutHeader({29handout,30status,31numStudents,32actions,33studentSearch,34setStudentSearch,35}: HandoutHeaderProps) {36const intl = useIntl();37const [openedRunAll, setOpenedRunAll] = useState<"distribution" | null>(null);3839useEffect(() => {40setOpenedRunAll(null);41}, [handout.get("handout_id")]);4243if (status == null) {44return null;45}46// Keep a narrowed alias since nested closures use this value and TS can47// lose the non-null guard on `status` across those closures.48const handoutStatus = status;4950function renderDistributionRunAll() {51return (52<RunAllPopover53id="distribution"54open={openedRunAll === "distribution"}55onOpenChange={(next) => setOpenedRunAll(next ? "distribution" : null)}56type={handoutStatus.not_handout > 0 ? "primary" : "default"}57content={58<CopyRunAllAlert59id="copy_confirm_handout"60step="distribution"61status={{62done: handoutStatus.handout,63not_done: handoutStatus.not_handout,64total: numStudents,65}}66onRun={({ scope, overwrite }) => {67// handout to all (non-deleted) students68actions.handouts.copy_handout_to_all_students(69handout.get("handout_id"),70scope === "remaining",71!!overwrite,72);73setOpenedRunAll(null);74}}75/>76}77ariaLabel={runAllAriaLabel(intl, "distribution")}78/>79);80}8182return (83<StudentAssignmentInfoHeader84mode="handout"85actions={{86distribution: [renderDistributionRunAll()],87}}88progress={{89distribution: (90<Progress91key="progress-handout"92done={handoutStatus.handout}93not_done={handoutStatus.not_handout}94step="distributed"95/>96),97}}98filter={99<DebounceInput100debounceTimeout={500}101element={Input as any}102placeholder={filterPlaceholder(intl)}103value={studentSearch}104onChange={(e) => setStudentSearch(e.target.value)}105/>106}107/>108);109}110111112