Merged in bug-fixing-280824 (pull request #83)

Bug fixing 280824

Approved-by: Tiago Ribeiro
This commit is contained in:
João Ramos
2024-08-28 08:57:52 +00:00
committed by Tiago Ribeiro
2 changed files with 65 additions and 17 deletions

View File

@@ -62,6 +62,30 @@ export default function AssignmentCard({
return resultModuleBandScores.length === 0 ? -1 : resultModuleBandScores.reduce((acc, curr) => acc + curr, 0) / results.length; return resultModuleBandScores.length === 0 ? -1 : resultModuleBandScores.reduce((acc, curr) => acc + curr, 0) / results.length;
}; };
const uniqModules = uniqBy(exams, (x) => x.module);
const shouldRenderPDF = () => {
if(released && allowDownload) {
// in order to be downloadable, the assignment has to be released
// the component should have the allowDownload prop
// and the assignment should not have the level module
return uniqModules.every(({ module }) => module !== 'level');
}
return false;
}
const shouldRenderExcel = () => {
if(released && allowExcelDownload) {
// in order to be downloadable, the assignment has to be released
// the component should have the allowExcelDownload prop
// and the assignment should have the level module
return uniqModules.some(({ module }) => module === 'level');
}
return false;
}
return ( return (
<div <div
onClick={onClick} onClick={onClick}
@@ -70,8 +94,8 @@ export default function AssignmentCard({
<div className="flex flex-row justify-between"> <div className="flex flex-row justify-between">
<h3 className="text-xl font-semibold">{name}</h3> <h3 className="text-xl font-semibold">{name}</h3>
<div className="flex gap-2"> <div className="flex gap-2">
{allowDownload && released && renderPdfIcon(id, "text-mti-gray-dim", "text-mti-gray-dim")} {shouldRenderPDF() && renderPdfIcon(id, "text-mti-gray-dim", "text-mti-gray-dim")}
{allowExcelDownload && released && renderExcelIcon(id, "text-mti-gray-dim", "text-mti-gray-dim")} {shouldRenderExcel() && renderExcelIcon(id, "text-mti-gray-dim", "text-mti-gray-dim")}
{allowArchive && !archived && renderArchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")} {allowArchive && !archived && renderArchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")}
{allowUnarchive && archived && renderUnarchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")} {allowUnarchive && archived && renderUnarchiveIcon("text-mti-gray-dim", "text-mti-gray-dim")}
{!released && renderReleaseIcon("text-mti-gray-dim", "text-mti-gray-dim")} {!released && renderReleaseIcon("text-mti-gray-dim", "text-mti-gray-dim")}
@@ -94,7 +118,7 @@ export default function AssignmentCard({
<span>Assigner: {getUserName(users.find((x) => x.id === assigner))}</span> <span>Assigner: {getUserName(users.find((x) => x.id === assigner))}</span>
</div> </div>
<div className="-md:mt-2 grid w-full grid-cols-4 place-items-start gap-2"> <div className="-md:mt-2 grid w-full grid-cols-4 place-items-start gap-2">
{uniqBy(exams, (x) => x.module).map(({module}) => ( {uniqModules.map(({module}) => (
<div <div
key={module} key={module}
className={clsx( className={clsx(

View File

@@ -84,9 +84,16 @@ function commonExcel({
.map((assignee: string) => { .map((assignee: string) => {
const userStats = allStats.filter((s: any) => s.user === assignee); const userStats = allStats.filter((s: any) => s.user === assignee);
const dates = userStats.map((s: any) => moment(s.date)); const dates = userStats.map((s: any) => moment(s.date));
const user = users.find((u) => u.id === assignee);
return { return {
userId: assignee, userId: assignee,
user: users.find((u) => u.id === assignee), // added some default values in case the user is not found
// could it be possible to have an assigned user deleted from the database?
user: user || {
name: "Unknown",
email: "Unknown",
demographicInformation: { passportId: "Unknown", gender: "Unknown" },
},
...userStats.reduce( ...userStats.reduce(
(acc: any, curr: any) => { (acc: any, curr: any) => {
return { return {
@@ -152,7 +159,7 @@ function commonExcel({
}); });
// added empty arrays to force row spacings // added empty arrays to force row spacings
const customTableAndLine = [[],...customTable, []]; const customTableAndLine = [[], ...customTable, []];
customTableAndLine.forEach((row: string[], index) => { customTableAndLine.forEach((row: string[], index) => {
worksheet.addRow(row); worksheet.addRow(row);
}); });
@@ -188,7 +195,8 @@ function commonExcel({
worksheet.addRow(tableColumnHeaders); worksheet.addRow(tableColumnHeaders);
// 1 headers rows // 1 headers rows
const startIndexTable = firstSectionData.length + customTableAndLine.length + 1; const startIndexTable =
firstSectionData.length + customTableAndLine.length + 1;
// // Merge "Test Sections" over dynamic number of columns // // Merge "Test Sections" over dynamic number of columns
// const tableColumns = staticHeaders.length + numberOfTestSections; // const tableColumns = staticHeaders.length + numberOfTestSections;
@@ -197,7 +205,7 @@ function commonExcel({
// horizontally group Test Sections // horizontally group Test Sections
// if there are test section headers to even merge: // if there are test section headers to even merge:
if(testSectionHeaders.length > 1) { if (testSectionHeaders.length > 1) {
worksheet.mergeCells( worksheet.mergeCells(
startIndexTable, startIndexTable,
staticHeaders.length + 1, staticHeaders.length + 1,
@@ -233,7 +241,12 @@ function commonExcel({
// vertically group based on the part, exercise and type // vertically group based on the part, exercise and type
staticHeaders.forEach((header, index) => { staticHeaders.forEach((header, index) => {
worksheet.mergeCells(startIndexTable, index + 1, startIndexTable + 3, index + 1); worksheet.mergeCells(
startIndexTable,
index + 1,
startIndexTable + 3,
index + 1
);
}); });
assigneesData.forEach((data, index) => { assigneesData.forEach((data, index) => {
@@ -320,13 +333,17 @@ async function mastercorporateAssignment(
const adminsData = await getSpecificUsers(adminUsers); const adminsData = await getSpecificUsers(adminUsers);
const companiesData = adminsData.map((user) => { const companiesData = adminsData.map((user) => {
const name = getUserName(user); const name = getUserName(user);
const users = userGroupsParticipants const users = userGroupsParticipants.filter((p) =>
.filter((p) => data.assignees.includes(p)); data.assignees.includes(p)
);
const stats = data.results const stats = data.results
.flatMap((r: any) => r.stats) .flatMap((r: any) => r.stats)
.filter((s: any) => users.includes(s.user)); .filter((s: any) => users.includes(s.user));
const correct = stats.reduce((acc: number, s: any) => acc + s.score.correct, 0); const correct = stats.reduce(
(acc: number, s: any) => acc + s.score.correct,
0
);
const total = stats.reduce( const total = stats.reduce(
(acc: number, curr: any) => acc + curr.score.total, (acc: number, curr: any) => acc + curr.score.total,
0 0
@@ -346,9 +363,11 @@ async function mastercorporateAssignment(
correct: companiesData.reduce((acc, curr) => acc + curr.correct, 0), correct: companiesData.reduce((acc, curr) => acc + curr.correct, 0),
total: companiesData.reduce((acc, curr) => acc + curr.total, 0), total: companiesData.reduce((acc, curr) => acc + curr.total, 0),
}, },
].map((c) => [c.name, `${c.correct}/${c.total}`]) ].map((c) => [c.name, `${c.correct}/${c.total}`]);
const customTableHeaders = [{ name: "Corporate", helper: (data: any) => data.user.corporateName}]; const customTableHeaders = [
{ name: "Corporate", helper: (data: any) => data.user.corporateName },
];
return commonExcel({ return commonExcel({
data, data,
userName: user.corporateInformation?.companyInformation?.name || "", userName: user.corporateInformation?.companyInformation?.name || "",
@@ -358,12 +377,13 @@ async function mastercorporateAssignment(
return { return {
...u, ...u,
corporateName: getUserName(admin), corporateName: getUserName(admin),
} };
}), }),
sectionName: "Master Corporate Name :", sectionName: "Master Corporate Name :",
customTable: [['Corporate Summary'], ...customTable], customTable: [["Corporate Summary"], ...customTable],
customTableHeaders: customTableHeaders.map((h) => h.name), customTableHeaders: customTableHeaders.map((h) => h.name),
renderCustomTableData: (data) => customTableHeaders.map((h) => h.helper(data)), renderCustomTableData: (data) =>
customTableHeaders.map((h) => h.helper(data)),
}); });
} }
@@ -415,7 +435,11 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
case "corporate": case "corporate":
return corporateAssignment(user as CorporateUser, data, users); return corporateAssignment(user as CorporateUser, data, users);
case "mastercorporate": case "mastercorporate":
return mastercorporateAssignment(user as MasterCorporateUser, data, users); return mastercorporateAssignment(
user as MasterCorporateUser,
data,
users
);
default: default:
throw new Error("Invalid user type"); throw new Error("Invalid user type");
} }