Refactor most getServerProps to fetch independent request in parallel and projected the data only to return the necessary fields and changed some functions

This commit is contained in:
José Marques Lima
2025-01-30 18:25:42 +00:00
parent 58aebaa66c
commit 98ba0bfc04
36 changed files with 5796 additions and 4058 deletions

View File

@@ -4,7 +4,7 @@ import Button from "@/components/Low/Button";
import Separator from "@/components/Low/Separator";
import ProfileSummary from "@/components/ProfileSummary";
import { Session } from "@/hooks/useSessions";
import { Grading } from "@/interfaces";
import { Grading, Module } from "@/interfaces";
import { EntityWithRoles } from "@/interfaces/entity";
import { Exam } from "@/interfaces/exam";
import { InviteWithEntity } from "@/interfaces/invite";
@@ -12,14 +12,13 @@ import { Assignment } from "@/interfaces/results";
import { Stat, User } from "@/interfaces/user";
import { sessionOptions } from "@/lib/session";
import useExamStore from "@/stores/exam";
import { filterBy, findBy, mapBy, redirect, serialize } from "@/utils";
import { findBy, mapBy, redirect, serialize } from "@/utils";
import { requestUser } from "@/utils/api";
import {
activeAssignmentFilter,
futureAssignmentFilter,
} from "@/utils/assignments";
import { getAssignmentsByAssignee } from "@/utils/assignments.be";
import { getEntitiesWithRoles } from "@/utils/entities.be";
import { getExamsByIds } from "@/utils/exams.be";
import { sortByModule } from "@/utils/moduleUtils";
import { checkAccess } from "@/utils/permissions";
@@ -53,32 +52,59 @@ export const getServerSideProps = withIronSessionSsr(async ({ req, res }) => {
if (!checkAccess(user, ["admin", "developer", "student"]))
return redirect("/");
const assignments = (await getAssignmentsByAssignee(
user.id,
{
archived: { $ne: true },
},
{
_id: 0,
id: 1,
name: 1,
startDate: 1,
endDate: 1,
exams: 1,
results: 1,
},
{
sort: { startDate: 1 },
}
)) as Assignment[];
const entityIDS = mapBy(user.entities, "id") || [];
const entities = await getEntitiesWithRoles(entityIDS);
const assignments = await getAssignmentsByAssignee(user.id, {
archived: { $ne: true },
});
const sessions = await getSessionsByUser(user.id, 0, {
"assignment.id": { $in: mapBy(assignments, "id") },
});
const sessions = await getSessionsByUser(
user.id,
0,
{
"assignment.id": { $in: mapBy(assignments, "id") },
},
{
_id: 0,
id: 1,
assignment: 1,
}
);
const examIDs = uniqBy(
assignments.flatMap((a) =>
filterBy(a.exams, "assignee", user.id).map(
(e: any) => ({
module: e.module,
id: e.id,
key: `${e.module}_${e.id}`,
})
)
assignments.reduce<{ module: Module; id: string; key: string }[]>(
(acc, a) => {
a.exams.forEach((e) => {
if (e.assignee === user.id)
acc.push({
module: e.module,
id: e.id,
key: `${e.module}_${e.id}`,
});
});
return acc;
},
[]
),
"key"
);
const exams = await getExamsByIds(examIDs);
return { props: serialize({ user, entities, assignments, exams, sessions }) };
return { props: serialize({ user, assignments, exams, sessions }) };
}, sessionOptions);
const destination = Buffer.from("/official-exam").toString("base64");
@@ -109,11 +135,12 @@ export default function OfficialExam({
});
if (assignmentExams.every((x) => !!x)) {
const sortedAssignmentExams = assignmentExams.sort(sortByModule);
dispatch({
type: "INIT_EXAM",
payload: {
exams: assignmentExams.sort(sortByModule),
modules: mapBy(assignmentExams.sort(sortByModule), "module"),
exams: sortedAssignmentExams,
modules: mapBy(sortedAssignmentExams, "module"),
assignment,
},
});
@@ -144,12 +171,16 @@ export default function OfficialExam({
[assignments]
);
const assignmentSessions = useMemo(
() =>
sessions.filter((s) =>
mapBy(studentAssignments, "id").includes(s.assignment?.id || "")
),
[sessions, studentAssignments]
const assignmentSessions = useMemo(() => {
const studentAssignmentsIDs = mapBy(studentAssignments, "id");
return sessions.filter((s) =>
studentAssignmentsIDs.includes(s.assignment?.id || "")
);
}, [sessions, studentAssignments]);
const entityLabels = useMemo(
() => mapBy(entities, "label")?.join(","),
[entities]
);
return (
@@ -167,7 +198,7 @@ export default function OfficialExam({
<>
{entities.length > 0 && (
<div className="absolute right-4 top-4 rounded-lg bg-neutral-200 px-2 py-1">
<b>{mapBy(entities, "label")?.join(", ")}</b>
<b>{entityLabels}</b>
</div>
)}
@@ -191,20 +222,18 @@ export default function OfficialExam({
<span className="text-mti-gray-taupe scrollbar-hide flex gap-8 overflow-x-scroll">
{studentAssignments.length === 0 &&
"Assignments will appear here. It seems that for now there are no assignments for you."}
{studentAssignments
.sort((a, b) => moment(a.startDate).diff(b.startDate))
.map((a) => (
<AssignmentCard
key={a.id}
assignment={a}
user={user}
session={assignmentSessions.find(
(s) => s.assignment?.id === a.id
)}
startAssignment={startAssignment}
resumeAssignment={loadSession}
/>
))}
{studentAssignments.map((a) => (
<AssignmentCard
key={a.id}
assignment={a}
user={user}
session={assignmentSessions.find(
(s) => s.assignment?.id === a.id
)}
startAssignment={startAssignment}
resumeAssignment={loadSession}
/>
))}
</span>
</section>