feat: bring assement weighting to engage

This commit is contained in:
2026-05-24 17:21:21 +09:30
parent fee79e8623
commit 4f6916d8b3
2 changed files with 105 additions and 26 deletions
@@ -0,0 +1,55 @@
const ENGAGE_STUDENT_STORAGE_KEY = () =>
`bsplus.engageTimetable.student.${location.origin}`;
/** Engage assessments URLs: /#?page=/assessments/{studentId}/{programme}:{metaclass}:{studentId} */
export function getEngageAssessmentStudentId(): string | null {
const hashMatch = window.location.hash.match(/\/assessments\/(\d+)/);
if (hashMatch?.[1]) return hashMatch[1];
return localStorage.getItem(ENGAGE_STUDENT_STORAGE_KEY());
}
function randomEngagePdfFileName(): string {
const token = Math.random().toString(36).slice(2, 10);
return `${token}.pdf`;
}
export async function requestEngageAssessmentPdf(params: {
assessmentID: string | number;
metaclassID: string | number;
studentID: string | number;
}): Promise<string> {
const fileName = randomEngagePdfFileName();
const cacheBuster = Math.random().toString(36).slice(2, 10);
const response = await fetch(
`${location.origin}/seqta/parent/print/assessment?${cacheBuster}`,
{
method: "POST",
headers: { "Content-Type": "application/json; charset=utf-8" },
credentials: "include",
body: JSON.stringify({
id: params.assessmentID,
metaclass: params.metaclassID,
student: Number(params.studentID),
fileName,
}),
},
);
if (!response.ok) {
throw new Error(
`Failed to generate PDF: ${response.status} ${response.statusText}`,
);
}
const data = (await response.json()) as {
payload?: { file?: string };
};
return data.payload?.file ?? fileName;
}
export function getEngageAssessmentReportUrl(fileName: string): string {
return `${location.origin}/seqta/parent/report/get?file=${encodeURIComponent(fileName)}`;
}
@@ -1,5 +1,11 @@
import { getUserInfo } from "@/seqta/ui/AddBetterSEQTAElements.ts";
import ReactFiber from "@/seqta/utils/ReactFiber.ts";
import { isSeqtaEngageExperience } from "@/seqta/utils/isSeqtaEngage";
import {
getEngageAssessmentReportUrl,
getEngageAssessmentStudentId,
requestEngageAssessmentPdf,
} from "./engage.ts";
import {
ensurePdfjsWorker,
getPdfjsPageContextUrls,
@@ -464,8 +470,6 @@ export async function extractPDFText(url: string): Promise<string> {
async function handleWeightings(mark: any, api: any) {
const assessmentID = mark.id;
const metaclassID = mark.metaclassID;
const userInfo = await getUserInfo();
const userID = userInfo.id;
const title = mark.title;
if (
@@ -486,35 +490,55 @@ async function handleWeightings(mark: any, api: any) {
};
try {
const filename =
"BetterSEQTA-" +
String(Math.floor(Math.random() * 1e15)).padStart(15, "0");
let pdfUrl: string;
const printResponse = await fetch(
`${location.origin}/seqta/student/print/assessment`,
{
method: "POST",
headers: { "Content-Type": "application/json; charset=utf-8" },
credentials: "include",
body: JSON.stringify({
fileName: filename,
id: assessmentID,
metaclass: metaclassID,
student: userID,
}),
},
);
if (isSeqtaEngageExperience()) {
const studentID = getEngageAssessmentStudentId();
if (!studentID) {
throw new Error("Could not resolve Engage student ID from URL or storage");
}
if (!printResponse.ok) {
throw new Error(
`Failed to generate PDF: ${printResponse.status} ${printResponse.statusText}`,
const reportFile = await requestEngageAssessmentPdf({
assessmentID,
metaclassID,
studentID,
});
await new Promise((resolve) => setTimeout(resolve, 1000));
pdfUrl = getEngageAssessmentReportUrl(reportFile);
} else {
const userInfo = await getUserInfo();
const userID = userInfo.id;
const filename =
"BetterSEQTA-" +
String(Math.floor(Math.random() * 1e15)).padStart(15, "0");
const printResponse = await fetch(
`${location.origin}/seqta/student/print/assessment`,
{
method: "POST",
headers: { "Content-Type": "application/json; charset=utf-8" },
credentials: "include",
body: JSON.stringify({
fileName: filename,
id: assessmentID,
metaclass: metaclassID,
student: userID,
}),
},
);
if (!printResponse.ok) {
throw new Error(
`Failed to generate PDF: ${printResponse.status} ${printResponse.statusText}`,
);
}
await new Promise((resolve) => setTimeout(resolve, 1000));
pdfUrl = `${location.origin}/seqta/student/report/get?file=${filename}`;
}
await new Promise((resolve) => setTimeout(resolve, 1000));
const pdfUrl = `${location.origin}/seqta/student/report/get?file=${filename}`;
if (pdfUrl.startsWith("blob:")) {
throw new Error(`Cannot fetch blob URL from extension: ${pdfUrl}`);
}