Skip to content

Commit

Permalink
Merge pull request #2 from da-stoi/typescript-refactor
Browse files Browse the repository at this point in the history
Bug fixes and new features
  • Loading branch information
da-stoi authored Dec 13, 2022
2 parents 5918d27 + df16aca commit ea25652
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 26 deletions.
18 changes: 12 additions & 6 deletions src/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { configureSettings, displaySettings, getSettings } from "./settings";
import { getWeightGroups } from "./getWeightGroups";
import { Assignment, WeightGroups } from "./types";
import { displayInaccuracies } from "./getInaccuracies";
import { setOnlyGradedAssignmentsHandler } from "./onlyGradedAssignmentsToggle";

function gradesPage() {

Expand All @@ -35,16 +36,21 @@ function gradesPage() {
// Get user score
const userScore: number = getUserScore();

// Set the grade history
setGradeHistory(courseId, {
date: new Date(),
average: classAverage,
total: userScore
});
// Set the grade history only if the class average and user score are defined
if (classAverage && userScore) {
setGradeHistory(courseId, {
date: new Date(),
average: classAverage,
total: userScore
});
}

// Get the grade history
const gradeHistory = getGradeHistory(courseId);

// Set only graded assignments handler
setOnlyGradedAssignmentsHandler(gradeHistory, assignments, weightGroups);

// Display the class average
displayAverage(classAverage, userScore, gradeHistory);

Expand Down
91 changes: 82 additions & 9 deletions src/displayGradeData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { devLog } from "./devLog";
import { getGradesByWeightGroup } from "./getGradesByWeightGroup";
import { getUserScore } from "./getUserScore";
import { onlyGradedAssignments } from "./onlyGradedAssignmentsToggle";
import { getSettings } from "./settings";
import { Assignment, GradeHistory, WeightGroups } from "./types";

Expand All @@ -24,6 +25,7 @@ function gradeChangeSpan(previousScore: number, currentScore: number): string {
export function displayAverage(average: number, userScore: number, gradeHistory: GradeHistory[]) {
const finalGradeElement = document.getElementById('student-grades-right-content')?.querySelector('.final_grade');
const classAverageElement = document.createElement('div');
classAverageElement.id = 'cca-class-average';
classAverageElement.innerText = `Class Average: `;

// If there is no final grade element, return
Expand All @@ -32,8 +34,11 @@ export function displayAverage(average: number, userScore: number, gradeHistory:
return;
}

// Sort grade history by date
const sortedGradeHistory = gradeHistory.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());

// Get the previous average, or set it to the current average if there is no previous average
const previousAverage: number = gradeHistory.length <= 1 ? average : gradeHistory[gradeHistory.length - 2].average;
const previousAverage: number = sortedGradeHistory.length <= 1 ? average : sortedGradeHistory[1].average;

// Create the class average percent element
let averagePercentSpan: string = gradeChangeSpan(previousAverage, average);
Expand Down Expand Up @@ -61,6 +66,43 @@ export function displayAverage(average: number, userScore: number, gradeHistory:

}

// Update the average under the user's total score
export function updateAverageDisplay(average: number, userScore: number, gradeHistory: GradeHistory[]) {

const classAverageElement = document.getElementById('cca-class-average');

// If there is no final grade element, return
if (!classAverageElement) {
devLog('No class average element found', 'err');
return;
}

// Sort grade history by date
const sortedGradeHistory = gradeHistory.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());

// Get the previous average, or set it to the current average if there is no previous average
const previousAverage: number = sortedGradeHistory.length <= 1 ? average : sortedGradeHistory[0].average;

// Create the class average percent element
let averagePercentSpan: string = gradeChangeSpan(previousAverage, average);

// If enabled, display how the user's score compares to the class average
if (getSettings('averageComparison').value) {

if (average > userScore) {
const averageDifference = ((Math.abs(average - userScore) * 100).toFixed(2));
averagePercentSpan += `<span style="font-style: italic;"> (You are ${averageDifference}% behind the class average)</span>`;
} else if (average < userScore) {
const averageDifference = ((Math.abs(userScore - average) * 100).toFixed(2));
averagePercentSpan += `<span style="font-style: italic;"> (You are ${averageDifference}% ahead of the class average)</span>`;
}
}

// Add the average percent element to the class average element
classAverageElement.innerHTML = `Class Average: ${averagePercentSpan}`;

}

// Display user's grade change
export function displayGradeChange(gradeHistory: GradeHistory[]) {
const finalGradeElement = document.getElementById('student-grades-right-content')?.querySelector('.final_grade');
Expand All @@ -71,8 +113,11 @@ export function displayGradeChange(gradeHistory: GradeHistory[]) {
return;
}

// Sort grade history by date
const sortedGradeHistory = gradeHistory.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());

// Get the previous user score
const previousScore: number = gradeHistory[gradeHistory.length - 2].total;
const previousScore: number = sortedGradeHistory[1].total;

// Create the new total percent element
const totalPercentSpan: string = gradeChangeSpan(previousScore, getUserScore());
Expand Down Expand Up @@ -184,23 +229,23 @@ export function displayGradeHistory(gradeHistory: GradeHistory[]) {
// Add table body
const gradeHistoryTableBody = document.createElement('tbody');

// Reverse the average history so the most recent is at the top
gradeHistory.reverse();
// Sort grade history by date
let sortedGradeHistory = gradeHistory.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());

// Remove the first element
gradeHistory.shift();
sortedGradeHistory.shift();
// Trim list to 10
gradeHistory = gradeHistory.slice(0, 10);
sortedGradeHistory = sortedGradeHistory.slice(0, 10);

// Add table rows
gradeHistory.forEach((gradeHistoryItem, index) => {
const previousGradeHistory = gradeHistory[index + 1];
sortedGradeHistory.forEach((gradeHistoryItem, index) => {
const previousGradeHistory = sortedGradeHistory[index + 1];
gradeHistoryTableBody.appendChild(gradeHistoryRow(gradeHistoryItem, previousGradeHistory));
});

// Append table body
gradeHistoryTable.appendChild(gradeHistoryTableBody);


const hideShowHistoryButton = hideShowGradeHistoryButton(gradeHistoryTable);

// Add the button to the DOM
Expand Down Expand Up @@ -261,9 +306,11 @@ export function displayAverageByWeightGroup(assignments: Assignment[], weightGro
// If the weight group average doesn't exist, return
if (!weightGroupAverage && weightGroupName !== 'total') {
averageCell.innerText = '-';
averageCell.classList.add('cca-no-score');
} else if (weightGroupName === 'total') {
// Populate the average cell with average
averageCell.innerText = `${(average * 100).toFixed(1)}%`;
averageCell.id = 'cca-weight-table-total-average';
} else {
// Populate the average cell with average
averageCell.innerText = `${((weightGroupAverage.average / weightGroupAverage.possible) * 100).toFixed(1)}%`;
Expand All @@ -275,6 +322,30 @@ export function displayAverageByWeightGroup(assignments: Assignment[], weightGro
});
}

// Update average by weight group
export function updateAverageAndScoreByWeightGroup(average: number, userScore: number) {
const averageCell = document.getElementById('cca-weight-table-total-average');
const scoreCell = document.getElementById('cca-weight-table-total-score');
const noScoreCells = Array.from(document.getElementsByClassName('cca-no-score'));

// Update the average cell
if (averageCell) {
averageCell.innerText = `${(average * 100).toFixed(1)}%`;
}

// Update the users score cell
if (scoreCell) {
scoreCell.innerText = `${(userScore * 100).toFixed(1)}%`;
}

// Update the no score cells
if (noScoreCells.length > 0) {
noScoreCells.forEach((noScoreCell) => {
noScoreCell.textContent = onlyGradedAssignments() ? '-' : '0%';
});
}
}

// Display user's score by weight group
export function displayScoreByWeightGroup(assignments: Assignment[], weightGroups: WeightGroups, userScore: number) {

Expand Down Expand Up @@ -320,9 +391,11 @@ export function displayScoreByWeightGroup(assignments: Assignment[], weightGroup
// If the weight group score doesn't exist, return
if (!weightGroupScore && weightGroupName !== 'total') {
scoreCell.innerText = '-';
scoreCell.classList.add('cca-no-score');
} else if (weightGroupName === 'total') {
// Populate the score cell with score
scoreCell.innerText = `${(userScore * 100).toFixed(1)}%`;
scoreCell.id = 'cca-weight-table-total-score';
} else {
// Populate the score cell with score
scoreCell.innerText = `${((weightGroupScore.score / weightGroupScore.possible) * 100).toFixed(1)}%`;
Expand Down
19 changes: 11 additions & 8 deletions src/getClassAverage.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { getGradesByWeightGroup } from "./getGradesByWeightGroup";
import { onlyGradedAssignments } from "./onlyGradedAssignmentsToggle";
import { Assignment, GroupScores, WeightGroups } from "./types";

export function getClassAverage(assignmentList: Assignment[], weightGroups: WeightGroups): number {
export function getClassAverage(assignments: Assignment[], weightGroups: WeightGroups): number {

// Get group scores
const groupScores: GroupScores = getGradesByWeightGroup(assignmentList, weightGroups);
const groupScores: GroupScores = getGradesByWeightGroup(assignments, weightGroups);

let classAverage = 0;

Expand All @@ -14,14 +15,16 @@ export function getClassAverage(assignmentList: Assignment[], weightGroups: Weig
classAverage += (groupScore.average / groupScore.possible) * weightGroups[group];
}

// Adjust total for missing weight group averages
for (const group in weightGroups) {
if (!groupScores[group] && group !== 'total' && weightGroups[group] > 0) {
weightGroups.total -= weightGroups[group];
// Add percentage for missing weights if only graded assignments is checked
let totalMissingWeight = 1 - weightGroups.total;
if (onlyGradedAssignments()) {
for (const group in weightGroups) {
if (!groupScores[group] && group !== 'total' && weightGroups[group] > 0) {
totalMissingWeight += weightGroups[group];
}
}
}


// Return the average of all assignments
return classAverage / weightGroups.total;
return classAverage + totalMissingWeight;
}
4 changes: 2 additions & 2 deletions src/getGradesByWeightGroup.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { devLog } from "./devLog";
import { Assignment, GroupScores, WeightGroups } from "./types";

export function getGradesByWeightGroup(assignmentList: Assignment[], weightGroups: WeightGroups): GroupScores {
export function getGradesByWeightGroup(assignments: Assignment[], weightGroups: WeightGroups): GroupScores {

let groupScores: GroupScores = {};

// For each assignment, calculate the weighted score
assignmentList.forEach((assignment: Assignment) => {
assignments.forEach((assignment: Assignment) => {
if (assignment.countsTowardsFinal && !assignment.dropped && assignment.hasAverage) {

if (Object.keys(weightGroups).length <= 1 || !assignment.group || !weightGroups[assignment.group]) {
Expand Down
10 changes: 9 additions & 1 deletion src/gradeHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@ export function getGradeHistory(courseId: number): GradeHistory[] {
return [];
}

const parsedGradeHistory = JSON.parse(gradeHistory);

// Sort grade history by date
const sortedGradeHistory = parsedGradeHistory.sort((a: GradeHistory, b: GradeHistory) => {
return new Date(a.date).getTime() - new Date(b.date).getTime();
});


// Return the parsed grade history
return JSON.parse(gradeHistory);
return sortedGradeHistory;
}

export function setGradeHistory(courseId: number, gradeHistory: GradeHistory) {
Expand Down
35 changes: 35 additions & 0 deletions src/onlyGradedAssignmentsToggle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { displayGradeChange, updateAverageAndScoreByWeightGroup, updateAverageDisplay } from "./displayGradeData";
import { getClassAverage } from "./getClassAverage";
import { getUserScore } from "./getUserScore";
import { Assignment, GradeHistory, WeightGroups } from "./types";

export function onlyGradedAssignments(): boolean {
// Get the checkbox
const checkbox = document.getElementById("only_consider_graded_assignments") as HTMLInputElement;
const onlyGradedAssignments = checkbox.checked;

return onlyGradedAssignments;
}

function updateGradeData(gradeHistory: GradeHistory[], assignments: Assignment[], weightGroups: WeightGroups) {

const average = getClassAverage(assignments, weightGroups);
const userScore = getUserScore();

// Update the average
updateAverageDisplay(average, userScore, gradeHistory);

// Update user's score
displayGradeChange(gradeHistory);

// Update totals in weight table
updateAverageAndScoreByWeightGroup(average, userScore);
}

export function setOnlyGradedAssignmentsHandler(gradeHistory: GradeHistory[], assignments: Assignment[], weightGroups: WeightGroups) {
const checkbox = document.getElementById("only_consider_graded_assignments") as HTMLInputElement;
checkbox.addEventListener("change", () => {
// Update the average
updateGradeData(gradeHistory, assignments, weightGroups);
});
}

0 comments on commit ea25652

Please sign in to comment.