diff --git a/src/plugins/built-in/assessmentsAverage/index.ts b/src/plugins/built-in/assessmentsAverage/index.ts index af9d915d..be3b6bd4 100644 --- a/src/plugins/built-in/assessmentsAverage/index.ts +++ b/src/plugins/built-in/assessmentsAverage/index.ts @@ -8,7 +8,7 @@ import { type Plugin } from "@/plugins/core/types"; import stringToHTML from "@/seqta/utils/stringToHTML"; import { waitForElm } from "@/seqta/utils/waitForElm"; import ReactFiber from "@/seqta/utils/ReactFiber.ts"; -import { clearStuck, createWeightLabel, getClassByPattern, initStorage, letterToNumber, parseAssessments, parseGrade} from "./utils.ts"; +import { clearStuck, getClassByPattern, initStorage, letterToNumber, parseAssessments, processAssessments} from "./utils.ts"; // Storage interface weightingsStorage { @@ -128,68 +128,13 @@ const assessmentsAveragePlugin: Plugin = { !item.querySelector(`[class*='AssessmentItem__title___']`)?.textContent?.includes("Subject Average"), ); - // Match marks to assessment items and calculate weighted average - let weightedTotal = 0; - let totalWeight = 0; - let hasInaccurateWeighting = false; - let count = 0; - - // Iterate through assessments for processing - for (const assessmentItem of assessmentItems) { - const gradeElement = assessmentItem.querySelector( - `[class*='Thermoscore__text___']`, - ); - - if (!gradeElement) continue; - - const grade = parseGrade(gradeElement.textContent || ""); - if (grade <= 0) continue; - - const titleEl = assessmentItem.querySelector( - `[class*='AssessmentItem__title___']`, - ); - if (!titleEl) continue; - - const title = titleEl.textContent?.trim(); - if (!title) continue; - - // Get correlated assessment ID in order to fetch weightings - const assessmentID = api.storage.assessments?.[title]; - const weighting = assessmentID - ? api.storage.weightings?.[assessmentID] - : undefined; - - - // Creates a weighting label next to the average score - createWeightLabel(assessmentItem, weighting) - - // Check if weighting is unavailable or still processing - if ( - weighting === null || - weighting === undefined || - weighting === "N/A" || - weighting === "processing" - ) { - hasInaccurateWeighting = true; - // Fall back to equal weighting if unavailable - weightedTotal += grade; - totalWeight += 1; - } else { - const weight = parseFloat(weighting); - - // If weight is a positive number, add to total - if (!isNaN(weight) && weight >= 0) { - weightedTotal += grade * weight; - totalWeight += weight; - } else { - // Invalid weight, use equal weighting - weightedTotal += grade; - totalWeight += 1; - hasInaccurateWeighting = true; - } - } - count++; - } + // Tally up weightedTotal, totalWeight, count, determine if weighting is accurate, and display a weight label per assessment + const { + weightedTotal, + totalWeight, + hasInaccurateWeighting, + count, + } = await processAssessments(api, assessmentItems); if (!count || totalWeight === 0) return; diff --git a/src/plugins/built-in/assessmentsAverage/utils.ts b/src/plugins/built-in/assessmentsAverage/utils.ts index 8d4c035e..320dd3a9 100644 --- a/src/plugins/built-in/assessmentsAverage/utils.ts +++ b/src/plugins/built-in/assessmentsAverage/utils.ts @@ -60,7 +60,7 @@ export const letterToNumber: Record = { F: 0, }; -export function parseGrade(text: string): number { +function parseGrade(text: string): number { const str = text.trim().toUpperCase(); if (str.includes("/")) { const [raw, max] = str.split("/").map((n) => parseFloat(n)); @@ -72,7 +72,7 @@ export function parseGrade(text: string): number { return letterToNumber[str] ?? 0; } -export function createWeightLabel(assessmentItem: Element, weighting: string | undefined) { +function createWeightLabel(assessmentItem: Element, weighting: string | undefined) { const statsContainer = assessmentItem.querySelector( `[class*='AssessmentItem__stats___']`, ) as HTMLElement; @@ -553,3 +553,73 @@ export async function parseAssessments(api: any) { // Dispatch for all assessments asynchronously await Promise.all(marks.map((mark: any) => handleWeightings(mark, api))); } + +// Tally up weightedTotal, totalWeight, count, determine if weighting is accurate, and display a weight label per assessment +export async function processAssessments(api: any, assessmentItems: Element[]) { + let weightedTotal = 0; + let totalWeight = 0; + let hasInaccurateWeighting = false; + let count = 0; + + for (const assessmentItem of assessmentItems) { + const gradeElement = assessmentItem.querySelector( + `[class*='Thermoscore__text___']`, + ); + + if (!gradeElement) continue; + + const grade = parseGrade(gradeElement.textContent || ""); + if (grade <= 0) continue; + + const titleEl = assessmentItem.querySelector( + `[class*='AssessmentItem__title___']`, + ); + if (!titleEl) continue; + + const title = titleEl.textContent?.trim(); + if (!title) continue; + + // Get correlated assessment ID in order to fetch weightings + const assessmentID = api.storage.assessments?.[title]; + const weighting = assessmentID + ? api.storage.weightings?.[assessmentID] + : undefined; + + // Creates a weighting label next to the average score + createWeightLabel(assessmentItem, weighting); + + // Check if weighting is unavailable or still processing + if ( + weighting === null || + weighting === undefined || + weighting === "N/A" || + weighting === "processing" + ) { + hasInaccurateWeighting = true; + // Fall back to equal weighting if unavailable + weightedTotal += grade; + totalWeight += 1; + } else { + const weight = parseFloat(weighting); + + // If weight is a positive number, add to total + if (!isNaN(weight) && weight >= 0) { + weightedTotal += grade * weight; + totalWeight += weight; + } else { + // Invalid weight, use equal weighting + weightedTotal += grade; + totalWeight += 1; + hasInaccurateWeighting = true; + } + } + count++; + } + + return { + weightedTotal, + totalWeight, + hasInaccurateWeighting, + count, + }; +} \ No newline at end of file