Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/course/common/copy-run-all.tsx
10799 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { Alert, Button, Input, Space } from "antd";
7
import { useEffect, useState } from "react";
8
import { useIntl } from "react-intl";
9
10
import { Icon } from "@cocalc/frontend/components";
11
import type { AssignmentCopyStep, CopyStep } from "../types";
12
import {
13
copyConfirmAllCaution,
14
handoutCopyConfirmAllCaution,
15
} from "./course-unit-strings";
16
import {
17
allStudents,
18
commonMsgs,
19
remainingStudents,
20
runAllIntro,
21
} from "./copy-run-all-messages";
22
23
interface CopyRunAllAlertProps {
24
id: string;
25
step: CopyStep;
26
status: { done: number; not_done: number; total: number };
27
onRun: (opts: { scope: "remaining" | "all"; overwrite?: boolean }) => void;
28
hasStudentSubdir?: boolean;
29
}
30
31
export function CopyRunAllAlert({
32
id,
33
step,
34
status,
35
onRun,
36
hasStudentSubdir = false,
37
}: CopyRunAllAlertProps) {
38
const intl = useIntl();
39
const overwriteToken = "OVERWRITE";
40
const [confirmAll, setConfirmAll] = useState<boolean>(false);
41
const [confirmOverwrite, setConfirmOverwrite] = useState<boolean>(false);
42
const [confirmOverwriteText, setConfirmOverwriteText] = useState<string>("");
43
44
useEffect(() => {
45
setConfirmAll(false);
46
setConfirmOverwrite(false);
47
setConfirmOverwriteText("");
48
}, [id]);
49
50
const { done, not_done, total } = status;
51
const cautionContent =
52
step === "distribution"
53
? handoutCopyConfirmAllCaution(intl)
54
: copyConfirmAllCaution(intl, step as AssignmentCopyStep);
55
const allowOverwrite = step === "assignment" || step === "distribution";
56
const possible = done + not_done;
57
const showNewButton = not_done > 0 && !confirmAll;
58
const alertType = confirmAll
59
? "error"
60
: showNewButton
61
? "warning"
62
: "success";
63
const msg = commonMsgs(intl, overwriteToken);
64
65
function render_confirm_overwrite() {
66
if (!confirmOverwrite) return null;
67
return (
68
<Space direction="vertical">
69
{msg.typeOverwrite}
70
<Input
71
autoFocus
72
onChange={(e) => setConfirmOverwriteText((e.target as any).value)}
73
/>
74
<Button
75
disabled={confirmOverwriteText !== overwriteToken}
76
icon={<Icon name="exclamation-triangle" />}
77
danger
78
type="primary"
79
onClick={() => {
80
onRun({ scope: "all", overwrite: true });
81
setConfirmOverwrite(false);
82
setConfirmOverwriteText("");
83
}}
84
>
85
{msg.confirmWithoutBackup}
86
</Button>
87
</Space>
88
);
89
}
90
91
function render_confirm_all() {
92
return (
93
<Space direction="vertical" key="confirm-all">
94
{cautionContent}
95
<Space wrap>
96
<Button
97
key="all"
98
type="primary"
99
disabled={confirmOverwrite}
100
onClick={() => onRun({ scope: "all" })}
101
>
102
{msg.withBackup}
103
</Button>
104
{allowOverwrite ? (
105
<Button
106
key="all-overwrite"
107
danger
108
onClick={() => setConfirmOverwrite(true)}
109
disabled={confirmOverwrite}
110
>
111
{msg.withoutBackup}
112
</Button>
113
) : undefined}
114
<Button
115
key="back"
116
onClick={() => {
117
setConfirmAll(false);
118
setConfirmOverwrite(false);
119
}}
120
>
121
{msg.back}
122
</Button>
123
</Space>
124
{render_confirm_overwrite()}
125
</Space>
126
);
127
}
128
129
const message = (
130
<Space
131
direction="vertical"
132
style={{ display: "inline-flex", alignItems: "stretch" }}
133
>
134
{step === "assignment" && hasStudentSubdir ? (
135
<Alert
136
type="info"
137
message={
138
<span>
139
{msg.studentSubdirInfo}{" "}
140
<a
141
rel="noopener noreferrer"
142
target="_blank"
143
href="https://doc.cocalc.com/teaching-nbgrader.html#student-version"
144
>
145
{msg.nbgraderDocs}
146
</a>
147
</span>
148
}
149
/>
150
) : null}
151
<div>{runAllIntro(intl, step)}</div>
152
{showNewButton ? (
153
<Button
154
key="new"
155
type="primary"
156
onClick={() => onRun({ scope: "remaining" })}
157
>
158
{not_done === total ? (
159
<>{allStudents(intl, step, total)}</>
160
) : (
161
<>{remainingStudents(intl, step, not_done)}</>
162
)}
163
</Button>
164
) : undefined}
165
{not_done !== possible ? (
166
<Button
167
key="all"
168
danger
169
disabled={confirmAll}
170
onClick={() => setConfirmAll(true)}
171
>
172
{allStudents(intl, step, possible)}...
173
</Button>
174
) : undefined}
175
{confirmAll ? render_confirm_all() : undefined}
176
</Space>
177
);
178
179
return <Alert key={id} type={alertType} message={message} />;
180
}
181
182