CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/course/handouts/handout-student-list.tsx
Views: 687
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 { redux } from "@cocalc/frontend/app-framework";
7
import { useMemo } from "react";
8
import ScrollableList from "@cocalc/frontend/components/scrollable-list";
9
import { cmp, trunc_middle } from "@cocalc/util/misc";
10
import { UserMap } from "../../todo-types";
11
import { CourseActions } from "../actions";
12
import { CourseStore, HandoutRecord, StudentsMap } from "../store";
13
import * as util from "../util";
14
import { StudentHandoutInfoHeader } from "./handout-info-header";
15
import { StudentHandoutInfo } from "./handouts-info-panel";
16
17
interface StudentListForHandoutProps {
18
frame_id?: string;
19
name: string;
20
user_map: UserMap;
21
students: StudentsMap;
22
handout: HandoutRecord;
23
actions: CourseActions;
24
}
25
26
export function StudentListForHandout({
27
frame_id,
28
name,
29
user_map,
30
students,
31
handout,
32
actions,
33
}: StudentListForHandoutProps) {
34
const student_list = useMemo(() => {
35
const v0: any[] = util.immutable_to_list(students, "student_id");
36
37
// Remove deleted students
38
const v1: any[] = [];
39
for (const x of v0) {
40
if (!x.deleted) v1.push(x);
41
const user = user_map.get(x.account_id);
42
if (user != null) {
43
const first_name = user.get("first_name", "");
44
const last_name = user.get("last_name", "");
45
x.sort = (last_name + " " + first_name).toLowerCase();
46
} else if (x.email_address != null) {
47
x.sort = x.email_address.toLowerCase();
48
}
49
}
50
v1.sort((a, b) => cmp(a.sort, b.sort));
51
const student_list: string[] = v1.map((x) => x.student_id);
52
return student_list;
53
}, [students, user_map]);
54
55
function get_store(): CourseStore {
56
const store = redux.getStore(name);
57
if (store == null) throw Error("store must be defined");
58
return store as unknown as CourseStore;
59
}
60
61
function render_students() {
62
return (
63
<ScrollableList
64
virtualize
65
rowCount={student_list.length}
66
rowRenderer={({ key }) => render_student_info(key)}
67
rowKey={(index) => student_list[index]}
68
cacheId={`course-handout-${handout.get("handout_id")}-${
69
actions.name
70
}-${frame_id}`}
71
/>
72
);
73
}
74
75
function render_student_info(student_id: string) {
76
const info = get_store().student_handout_info(
77
student_id,
78
handout.get("handout_id"),
79
);
80
return (
81
<StudentHandoutInfo
82
key={student_id}
83
actions={actions}
84
info={info}
85
title={trunc_middle(get_store().get_student_name(student_id), 40)}
86
/>
87
);
88
}
89
90
return (
91
<div style={{ height: "70vh", display: "flex", flexDirection: "column" }}>
92
<StudentHandoutInfoHeader key="header" title="Student" />
93
{render_students()}
94
</div>
95
);
96
}
97
98