Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/course/assignments/assignment-student-list.tsx
1503 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 { useIntl } from "react-intl";
7
8
// CoCalc libraries
9
import { AppRedux, useMemo, useRedux } from "@cocalc/frontend/app-framework";
10
import ScrollableList from "@cocalc/frontend/components/scrollable-list";
11
import { search_match, search_split, trunc_middle } from "@cocalc/util/misc";
12
import { StudentAssignmentInfo, StudentAssignmentInfoHeader } from "../common";
13
import type {
14
AssignmentRecord,
15
CourseStore,
16
IsGradingMap,
17
NBgraderRunInfo,
18
SortDescription,
19
} from "../store";
20
import {
21
assignment_identifier,
22
parse_students,
23
pick_student_sorter,
24
} from "../util";
25
26
interface StudentListForAssignmentProps {
27
frame_id?: string;
28
name: string;
29
redux: AppRedux;
30
assignment: AssignmentRecord;
31
students: any;
32
user_map: any;
33
active_feedback_edits: IsGradingMap;
34
nbgrader_run_info?: NBgraderRunInfo;
35
search: string;
36
}
37
38
export function StudentListForAssignment({
39
frame_id,
40
name,
41
redux,
42
assignment,
43
students,
44
user_map,
45
active_feedback_edits,
46
nbgrader_run_info,
47
search,
48
}: StudentListForAssignmentProps) {
49
const intl = useIntl();
50
51
const active_student_sort: SortDescription = useRedux(
52
name,
53
"active_student_sort",
54
);
55
const student_list: string[] = useMemo(() => {
56
const v0 = parse_students(students, user_map, redux, intl);
57
const store = get_store();
58
59
// Remove deleted students or students not matching the search
60
const terms = search_split(search);
61
const v1: any[] = [];
62
for (const x of v0) {
63
if (x.deleted) continue;
64
if (
65
terms.length > 0 &&
66
!search_match(store.get_student_name(x.student_id).toLowerCase(), terms)
67
) {
68
continue;
69
}
70
v1.push(x);
71
}
72
73
v1.sort(pick_student_sorter(active_student_sort.toJS()));
74
75
return v1.map((x) => x.student_id);
76
}, [
77
students,
78
user_map,
79
active_student_sort,
80
active_feedback_edits,
81
nbgrader_run_info,
82
search,
83
]);
84
85
function get_store(): CourseStore {
86
return redux.getStore(name) as any;
87
}
88
89
function is_peer_graded(): boolean {
90
const peer_info = assignment.get("peer_grade");
91
return peer_info ? peer_info.get("enabled") : false;
92
}
93
94
function render_student_info(student_id: string) {
95
const store = get_store();
96
const student = store.get_student(student_id);
97
if (student == null) return; // no such student
98
const key = assignment_identifier(
99
assignment.get("assignment_id"),
100
student_id,
101
);
102
const edited_feedback = active_feedback_edits.get(key);
103
return (
104
<StudentAssignmentInfo
105
key={student_id}
106
title={trunc_middle(store.get_student_name(student_id), 40)}
107
name={name}
108
student={student}
109
assignment={assignment}
110
grade={store.get_grade(assignment.get("assignment_id"), student_id)}
111
nbgrader_scores={store.get_nbgrader_scores(
112
assignment.get("assignment_id"),
113
student_id,
114
)}
115
nbgrader_score_ids={store.get_nbgrader_score_ids(
116
assignment.get("assignment_id"),
117
)}
118
comments={store.get_comments(
119
assignment.get("assignment_id"),
120
student_id,
121
)}
122
info={store.student_assignment_info(
123
student_id,
124
assignment.get("assignment_id"),
125
)}
126
is_editing={!!edited_feedback}
127
nbgrader_run_info={nbgrader_run_info}
128
/>
129
);
130
}
131
132
function render_students() {
133
return (
134
<ScrollableList
135
virtualize
136
rowCount={student_list.length}
137
rowRenderer={({ key }) => render_student_info(key)}
138
rowKey={(index) => student_list[index]}
139
cacheId={`course-assignment-${assignment.get(
140
"assignment_id",
141
)}-${name}-${frame_id}`}
142
/>
143
);
144
}
145
146
return (
147
<div style={{ height: "70vh", display: "flex", flexDirection: "column" }}>
148
<StudentAssignmentInfoHeader
149
key="header"
150
title="Student"
151
peer_grade={is_peer_graded()}
152
/>
153
{render_students()}
154
</div>
155
);
156
}
157
158