diff --git a/public/js/buttonFunctions.js b/public/js/buttonFunctions.js
index 012328ea..74d67123 100755
--- a/public/js/buttonFunctions.js
+++ b/public/js/buttonFunctions.js
@@ -1,12 +1,12 @@
let newAssignment = function() {
- tableData.currentTermData.classes[selected_class_i].edited = true;
+ currentTableData.currentTermData.classes[selected_class_i].edited = true;
if (!isNaN(selected_class_i)) {
- tableData.currentTermData.classes[selected_class_i].assignments.unshift({
+ currentTableData.currentTermData.classes[selected_class_i].assignments.unshift({
"name": "Assignment",
- "category": Object.keys(tableData.currentTermData.classes[selected_class_i].categories)[0],
+ "category": Object.keys(currentTableData.currentTermData.classes[selected_class_i].categories)[0],
"score": 10,
"max_score": 10,
"percentage": 100,
@@ -21,27 +21,27 @@ let newAssignment = function() {
let editAssignment = function(data) {
- tableData.currentTermData.classes[selected_class_i].edited = true;
+ currentTableData.currentTermData.classes[selected_class_i].edited = true;
- tableData.currentTermData.classes[selected_class_i].assignments = data.slice();
+ currentTableData.currentTermData.classes[selected_class_i].assignments = data.slice();
- for (let j = 0; j < tableData.currentTermData.classes[selected_class_i].assignments.length; j++) {
- tableData.currentTermData.classes[selected_class_i].assignments[j].percentage = Math.round(tableData.currentTermData.classes[selected_class_i].assignments[j].score / tableData.currentTermData.classes[selected_class_i].assignments[j].max_score * 1000) / 10;
- tableData.currentTermData.classes[selected_class_i].assignments[j].color = getColor(tableData.currentTermData.classes[selected_class_i].assignments[j].percentage);
+ for (let j = 0; j < currentTableData.currentTermData.classes[selected_class_i].assignments.length; j++) {
+ currentTableData.currentTermData.classes[selected_class_i].assignments[j].percentage = Math.round(currentTableData.currentTermData.classes[selected_class_i].assignments[j].score / currentTableData.currentTermData.classes[selected_class_i].assignments[j].max_score * 1000) / 10;
+ currentTableData.currentTermData.classes[selected_class_i].assignments[j].color = getColor(currentTableData.currentTermData.classes[selected_class_i].assignments[j].percentage);
- if (tableData.currentTermData.classes[selected_class_i].assignments[j].category.includes("(")) {
- tableData.currentTermData.classes[selected_class_i].assignments[j].category = tableData.currentTermData.classes[selected_class_i].assignments[j].category.substring(0, tableData.currentTermData.classes[selected_class_i].assignments[j].category.indexOf("(") - 1);
+ if (currentTableData.currentTermData.classes[selected_class_i].assignments[j].category.includes("(")) {
+ currentTableData.currentTermData.classes[selected_class_i].assignments[j].category = currentTableData.currentTermData.classes[selected_class_i].assignments[j].category.substring(0, currentTableData.currentTermData.classes[selected_class_i].assignments[j].category.indexOf("(") - 1);
}
- if (isNaN(tableData.currentTermData.classes[selected_class_i].assignments[j].score) || tableData.currentTermData.classes[selected_class_i].assignments[j].score === "") {
- tableData.currentTermData.classes[selected_class_i].assignments[j].score = "None";
+ if (isNaN(currentTableData.currentTermData.classes[selected_class_i].assignments[j].score) || currentTableData.currentTermData.classes[selected_class_i].assignments[j].score === "") {
+ currentTableData.currentTermData.classes[selected_class_i].assignments[j].score = "None";
}
- if (isNaN(tableData.currentTermData.classes[selected_class_i].assignments[j].max_score) || tableData.currentTermData.classes[selected_class_i].assignments[j].max_score === "") {
- tableData.currentTermData.classes[selected_class_i].assignments[j].max_score = "None";
+ if (isNaN(currentTableData.currentTermData.classes[selected_class_i].assignments[j].max_score) || currentTableData.currentTermData.classes[selected_class_i].assignments[j].max_score === "") {
+ currentTableData.currentTermData.classes[selected_class_i].assignments[j].max_score = "None";
}
}
@@ -53,36 +53,36 @@ let editAssignment = function(data) {
let resetTableData = function() {
//tableData.currentTermData.classes[selected_class_i].edited = false;
- tableData.terms[currentTerm] = JSON.parse(JSON.stringify(termsReset[currentTerm]));
- tableData.currentTermData = tableData.terms[currentTerm];
+ currentTableData.terms[currentTerm] = JSON.parse(JSON.stringify(termsReset[currentTerm]));
+ currentTableData.currentTermData = currentTableData.terms[currentTerm];
if (selected_class_i) {
- assignmentsTable.setData(tableData.currentTermData.classes[selected_class_i].assignments);
- categoriesTable.setData(tableData.currentTermData.classes[selected_class_i].categoryDisplay);
+ assignmentsTable.setData(currentTableData.currentTermData.classes[selected_class_i].assignments);
+ categoriesTable.setData(currentTableData.currentTermData.classes[selected_class_i].categoryDisplay);
}
- classesTable.setData(tableData.currentTermData.classes);
+ classesTable.setData(currentTableData.currentTermData.classes);
- tableData.currentTermData.calcGPA = computeGPA(tableData.currentTermData.classes);
- let GPA = tableData.terms[currentTerm].GPA;
- let calcGPA = tableData.terms[currentTerm].calcGPA;
+ currentTableData.currentTermData.calcGPA = computeGPA(currentTableData.currentTermData.classes);
+ let GPA = currentTableData.terms[currentTerm].GPA;
+ let calcGPA = currentTableData.terms[currentTerm].calcGPA;
if (anyEdited()) {
//fix the editing system in the if statement above to be true if any of the classes are edited
if (currentTerm === "current") {
- $(".select-selected").css('padding', "5px 16px 5px 16px");
- $(".select-selected").html("Current Quarter GPA: " + GPA.percent + "
Calculated GPA: " + calcGPA.percent);
+ $(".gpa_select-selected").css('padding', "5px 16px 5px 16px");
+ $(".gpa_select-selected").html("Current Quarter GPA: " + GPA.percent + "
Calculated GPA: " + calcGPA.percent);
$("#" + currentTerm).css('padding', "5px 16px 5px 16px");
$("#" + currentTerm).html("Current Quarter GPA: " + GPA.percent + "
Calculated GPA: " + calcGPA.percent);
document.getElementById('gpa_select').options[0].innerHTML = "Current Quarter GPA: " + GPA.percent + "
Calculated GPA: " + calcGPA.percent;
document.getElementById('gpa_select').options[1].innerHTML = "Current Quarter GPA: " + GPA.percent + "
Calculated GPA: " + calcGPA.percent;
} else {
- tableData.currentTermData.calcGPA = computeGPA(tableData.currentTermData.classes);
+ currentTableData.currentTermData.calcGPA = computeGPA(currentTableData.currentTermData.classes);
- $(".select-selected").css('padding', "5px 16px 5px 16px");
- $(".select-selected").html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + GPA.percent + "
Calculated GPA: " + calcGPA.percent);
+ $(".gpa_select-selected").css('padding', "5px 16px 5px 16px");
+ $(".gpa_select-selected").html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + GPA.percent + "
Calculated GPA: " + calcGPA.percent);
$("#" + currentTerm).css('padding', "5px 16px 5px 16px");
$("#" + currentTerm).html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + GPA.percent + "
Calculated GPA: " + calcGPA.percent);
@@ -90,8 +90,8 @@ let resetTableData = function() {
}
} else {
if (currentTerm ==="current") {
- $(".select-selected").css("padding", "13px 16px 13px 16px");
- $(".select-selected").html("Current Quarter GPA: " + GPA.percent);
+ $(".gpa_select-selected").css("padding", "13px 16px 13px 16px");
+ $(".gpa_select-selected").html("Current Quarter GPA: " + GPA.percent);
$("#" + currentTerm).css("padding", "13px 16px 13px 16px");
$("#" + currentTerm).html("Current Quarter GPA: " + GPA.percent);
@@ -99,8 +99,8 @@ let resetTableData = function() {
document.getElementById('gpa_select').options[1].innerHTML = "Current Quarter GPA: " + GPA.percent;
} else {
- $(".select-selected").css("padding", "13px 16px 13px 16px");
- $(".select-selected").html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + GPA.percent);
+ $(".gpa_select-selected").css("padding", "13px 16px 13px 16px");
+ $(".gpa_select-selected").html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + GPA.percent);
$("#" + currentTerm).css("padding", "13px 16px 13px 16px");
$("#" + currentTerm).html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + GPA.percent);
@@ -116,32 +116,32 @@ let hideCategoriesTable = function() {
}
let updateGradePage = function() {
- let computingClassData = tableData.currentTermData.classes[selected_class_i];
+ let computingClassData = currentTableData.currentTermData.classes[selected_class_i];
let gradeInfo = (computeGrade(computingClassData.assignments, computingClassData.categories, computingClassData.decimals, computingClassData.init_calculated_grade, computingClassData.grade));
- tableData.currentTermData.classes[selected_class_i].calculated_grade = gradeInfo[computingClassData.type];
+ currentTableData.currentTermData.classes[selected_class_i].calculated_grade = gradeInfo[computingClassData.type];
- tableData.currentTermData.classes[selected_class_i].categoryDisplay = getCategoryDisplay(gradeInfo, computingClassData);
+ currentTableData.currentTermData.classes[selected_class_i].categoryDisplay = getCategoryDisplay(gradeInfo, computingClassData);
- classesTable.replaceData(tableData.currentTermData.classes);
- categoriesTable.setData(tableData.currentTermData.classes[selected_class_i].categoryDisplay);
+ classesTable.replaceData(currentTableData.currentTermData.classes);
+ categoriesTable.setData(currentTableData.currentTermData.classes[selected_class_i].categoryDisplay);
- assignmentsTable.replaceData(tableData.currentTermData.classes[selected_class_i].assignments);
+ assignmentsTable.replaceData(currentTableData.currentTermData.classes[selected_class_i].assignments);
- tableData.currentTermData.calcGPA = computeGPA(tableData.currentTermData.classes);
- tableData.terms[currentTerm].calcGPA = computeGPA(tableData.currentTermData.classes);
+ currentTableData.currentTermData.calcGPA = computeGPA(currentTableData.currentTermData.classes);
+ currentTableData.terms[currentTerm].calcGPA = computeGPA(currentTableData.currentTermData.classes);
- let GPA = tableData.terms[currentTerm].GPA;
- let calcGPA = tableData.terms[currentTerm].calcGPA;
+ let GPA = currentTableData.terms[currentTerm].GPA;
+ let calcGPA = currentTableData.terms[currentTerm].calcGPA;
if (anyEdited()) {
//fix the editing system in the if statement above to be true if any of the classes are edited
- $(".select-selected").css('padding', "5px 16px 5px 16px");
+ $(".gpa_select-selected").css('padding', "5px 16px 5px 16px");
- let selectedElem = $(".select-selected");
+ let selectedElem = $(".gpa_select-selected");
- let quarterData = tableData.terms[currentTerm];
+ let quarterData = currentTableData.terms[currentTerm];
let quarterName;
if (currentTerm === "current") {
@@ -155,14 +155,14 @@ let updateGradePage = function() {
if (selectedElem.html().includes("GPA")) {
if (quarterData.GPA.percent !== quarterData.calcGPA.percent) {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter GPA: " + tableData.terms.current.GPA.percent.toFixed(2) +
- "
Calculated: " + tableData.terms.current.calcGPA.percent.toFixed(2)
+ "Current Quarter GPA: " + currentTableData.terms.current.GPA.percent.toFixed(2) +
+ "
Calculated: " + currentTableData.terms.current.calcGPA.percent.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " GPA: " + tableData.terms["q" + i].GPA.percent.toFixed(2) +
- (tableData.terms["q" + i].calcGPA ? (
- "
Calculated: " + tableData.terms["q" + i].calcGPA.percent.toFixed(2)
+ "Q" + i + " GPA: " + currentTableData.terms["q" + i].GPA.percent.toFixed(2) +
+ (currentTableData.terms["q" + i].calcGPA ? (
+ "
Calculated: " + currentTableData.terms["q" + i].calcGPA.percent.toFixed(2)
) : "")
);
}
@@ -171,37 +171,37 @@ let updateGradePage = function() {
"
Calculated: " + quarterData.calcGPA.percent.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative GPA: " + tableData.cumGPA.percent.toFixed(2)
+ "Cumulative GPA: " + currentTableData.cumGPA.percent.toFixed(2)
);
}
else {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter GPA: " + tableData.terms.current.GPA.percent.toFixed(2)
+ "Current Quarter GPA: " + currentTableData.terms.current.GPA.percent.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " GPA: " + tableData.terms["q" + i].GPA.percent.toFixed(2)
+ "Q" + i + " GPA: " + currentTableData.terms["q" + i].GPA.percent.toFixed(2)
);
}
selectedElem.html(
quarterName + " GPA: " + quarterData.GPA.percent.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative GPA: " + tableData.cumGPA.percent.toFixed(2)
+ "Cumulative GPA: " + currentTableData.cumGPA.percent.toFixed(2)
);
}
}
else if (selectedElem.html().includes("Unweighted")) {
if (quarterData.GPA.outOfFour !== quarterData.calcGPA.outOfFour) {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter Unweighted: " + tableData.terms.current.GPA.outOfFour.toFixed(2) +
- "
Calculated: " + tableData.terms.current.calcGPA.outOfFour.toFixed(2)
+ "Current Quarter Unweighted: " + currentTableData.terms.current.GPA.outOfFour.toFixed(2) +
+ "
Calculated: " + currentTableData.terms.current.calcGPA.outOfFour.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " Unweighted: " + tableData.terms["q" + i].GPA.outOfFour.toFixed(2) +
- (tableData.terms["q" + i].calcGPA ? (
- "
Calculated: " + tableData.terms["q" + i].calcGPA.outOfFour.toFixed(2)
+ "Q" + i + " Unweighted: " + currentTableData.terms["q" + i].GPA.outOfFour.toFixed(2) +
+ (currentTableData.terms["q" + i].calcGPA ? (
+ "
Calculated: " + currentTableData.terms["q" + i].calcGPA.outOfFour.toFixed(2)
) : "")
);
}
@@ -210,37 +210,37 @@ let updateGradePage = function() {
"
Calculated: " + quarterData.calcGPA.outOfFour.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative Unweighted: " + tableData.cumGPA.outOfFour.toFixed(2)
+ "Cumulative Unweighted: " + currentTableData.cumGPA.outOfFour.toFixed(2)
);
}
else {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter Unweighted: " + tableData.terms.current.GPA.outOfFour.toFixed(2)
+ "Current Quarter Unweighted: " + currentTableData.terms.current.GPA.outOfFour.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " Unweighted: " + tableData.terms["q" + i].GPA.outOfFour.toFixed(2)
+ "Q" + i + " Unweighted: " + currentTableData.terms["q" + i].GPA.outOfFour.toFixed(2)
);
}
selectedElem.html(
quarterName + " Unweighted: " + quarterData.GPA.outOfFour.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative Unweighted: " + tableData.cumGPA.outOfFour.toFixed(2)
+ "Cumulative Unweighted: " + currentTableData.cumGPA.outOfFour.toFixed(2)
);
}
}
else if (selectedElem.html().includes("Weighted")) {
if (quarterData.GPA.outOfFive != quarterData.calcGPA.outOfFive) {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter Weighted: " + tableData.terms.current.GPA.outOfFive.toFixed(2) +
- "
Calculated: " + tableData.terms.current.calcGPA.outOfFive.toFixed(2)
+ "Current Quarter Weighted: " + currentTableData.terms.current.GPA.outOfFive.toFixed(2) +
+ "
Calculated: " + currentTableData.terms.current.calcGPA.outOfFive.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " Weighted: " + tableData.terms["q" + i].GPA.outOfFive.toFixed(2) +
- (tableData.terms["q" + i].calcGPA ? (
- "
Calculated: " + tableData.terms["q" + i].calcGPA.outOfFive.toFixed(2)
+ "Q" + i + " Weighted: " + currentTableData.terms["q" + i].GPA.outOfFive.toFixed(2) +
+ (currentTableData.terms["q" + i].calcGPA ? (
+ "
Calculated: " + currentTableData.terms["q" + i].calcGPA.outOfFive.toFixed(2)
) : "")
);
}
@@ -249,23 +249,23 @@ let updateGradePage = function() {
"
Calculated: " + quarterData.calcGPA.outOfFive.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative Weighted: " + tableData.cumGPA.outOfFive.toFixed(2)
+ "Cumulative Weighted: " + currentTableData.cumGPA.outOfFive.toFixed(2)
);
}
else {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter Weighted: " + tableData.terms.current.GPA.outOfFive.toFixed(2)
+ "Current Quarter Weighted: " + currentTableData.terms.current.GPA.outOfFive.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " Weighted: " + tableData.terms["q" + i].GPA.outOfFive.toFixed(2)
+ "Q" + i + " Weighted: " + currentTableData.terms["q" + i].GPA.outOfFive.toFixed(2)
);
}
selectedElem.html(
quarterName + " Weighted: " + quarterData.GPA.outOfFive.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative Weighted: " + tableData.cumGPA.outOfFive.toFixed(2)
+ "Cumulative Weighted: " + currentTableData.cumGPA.outOfFive.toFixed(2)
);
}
}
@@ -274,11 +274,206 @@ let updateGradePage = function() {
//+ "
"
//document.getElementById("GPA").innerHTML = "Quarter GPA: " + tableData.GPA + "
Calculated GPA: " + tableData.calcGPA + "
";
} else {
- $(".select-selected").css("padding", "13px 16px 13px 16px");
+ $(".gpa_select-selected").css("padding", "13px 16px 13px 16px");
$("#" + currentTerm).css("padding", "13px 16px 13px 16px");
- $(".select-selected").html("Quarter GPA: " + GPA.percent);
+ $(".gpa_select-selected").html("Quarter GPA: " + GPA.percent);
$("#" + currentTerm).html("Quarter GPA: " + GPA.percent);
}
}
-
\ No newline at end of file
+
+let exportTableData = async function(prefs) {
+ resetTableData();
+
+ let obj = {};
+
+//#ifndef lite
+ obj.version = await $.ajax("/version");
+//#endif
+
+//#ifdef lite
+/*
+ obj.version = (
+//#include $version
+ );
+*/
+//#endif
+
+ obj.username = currentTableData.username;
+ obj.overview = currentTableData.overview;
+
+ if (prefs.recent) obj.recent = currentTableData.recent;
+ if (prefs.schedule) obj.schedule = currentTableData.schedule;
+ if (prefs.terms) {
+ const origCurrentTerm = currentTerm;
+ try {
+ terms = await Promise.all(termConverter.map(async term => {
+ // Term is selected by user and its data are already downloaded
+ if (prefs.terms[term] && currentTableData.terms[term].classes) {
+ return currentTableData.terms[term];
+ }
+ // Term is selected by user and its data have not been downloaded
+ else if (prefs.terms[term] && !currentTableData.imported) {
+ try {
+ $("#export_status").html(
+ `Downloading quarter "${term}" from Aspen…`
+ );
+ const response = await $.ajax({
+ url: "/data",
+ method: "POST",
+ data: { quarter: parseInt(term.match(/\d+/)[0]) },
+ dataType: "json json"
+ });
+ currentTerm = term;
+ responseCallbackPartial(response);
+ $("#export_status").html("");
+ return currentTableData.terms[term];
+ }
+ catch (err) {
+ throw `Error while downloading quarter "${term}".`;
+ }
+ }
+ }));
+ obj.terms = {};
+ // Add the term data to obj.terms
+ termConverter.forEach((term, i) => {
+ if (terms[i]) {
+ obj.terms[term] = terms[i];
+ }
+ });
+ }
+ catch (err) {
+ $("#export_status").html(err);
+ return;
+ }
+ finally {
+ currentTerm = origCurrentTerm;
+ currentTableData.currentTermData = currentTableData.terms[currentTerm];
+ classesTable.setData(currentTableData.currentTermData.classes);
+ classesTable.redraw();
+ }
+ }
+ if (prefs.cumGPA) obj.cumGPA = currentTableData.cumGPA;
+
+ let jsonString = JSON.stringify(obj);
+
+ const filename = `aspine-export-${new Date().toISOString()}.json`;
+
+ $("#export_status").html(`Generated file "${filename}".`);
+
+ saveAs(new Blob([jsonString], {
+ type: "application/json;charset=utf-8"
+ }), filename);
+};
+
+let importTableData = async function(obj) {
+
+//#ifndef lite
+ let version = await $.ajax("/version");
+//#endif
+
+//#ifdef lite
+/*
+ let version = (
+//#include $version
+ );
+*/
+//#endif
+
+ let _ov, _v;
+ if (
+ (
+ // Check if major version differs
+ (_ov = parseInt(obj.version.match(/^v?(\d+)/)[1]))
+ !== (_v = parseInt(version.match(/^v?(\d+)/)[1]))
+ )
+ || (
+ // Check if minor version is newer
+ (_ov = parseInt(obj.version.match(/^v?\d+\.(\d+)/)[1]))
+ > (_v = parseInt(version.match(/^v?\d+\.(\d+)/)[1]))
+ )
+ ) {
+ return `This JSON file is from Aspine version ${obj.version} and is `
+ + `incompatible with Aspine version ${version}. `
+ + `${_ov < _v ? "Older" : "Newer"} versions of Aspine can be downloaded `
+ + `at
`
+ + `https://github.com/Aspine/aspine/releases.`;
+ }
+
+ currentTableDataIndex++;
+ tableData[currentTableDataIndex] = {};
+ currentTableData = tableData[currentTableDataIndex];
+ currentTableData.imported = true;
+ currentTableData.name = obj.name;
+
+ let includedTerms = {};
+ termConverter.forEach(term => {
+ if (obj.terms[term]) {
+ includedTerms[term] = true;
+ }
+ else {
+ includedTerms[term] = false;
+ }
+ });
+
+ currentTerm = "";
+ termConverter.forEach(term => {
+ if (!currentTerm && obj.terms[term]) currentTerm = term;
+ });
+ if (currentTerm) responseCallback({
+ username: obj.username || "",
+ recent: {
+ recentActivityArray: obj.recent.recentActivityArray || [],
+ recentAttendanceArray: obj.recent.recentAttendanceArray || []
+ },
+ overview: obj.overview || [],
+ classes: obj.terms[currentTerm].classes || [],
+ GPA: obj.terms[currentTerm].GPA || undefined,
+ cumGPA: obj.cumGPA || undefined
+ }, includedTerms);
+
+ scheduleCallback(obj.schedule || {});
+
+ let firstTerm = currentTerm;
+
+ termConverter.forEach(term => {
+ if (term === firstTerm || !obj.terms[term]) return;
+ currentTerm = term;
+ responseCallbackPartial({
+ classes: obj.terms[currentTerm].classes || []
+ });
+ });
+
+ currentTerm = firstTerm;
+
+ for (const i in tableData) {
+ if (!$(`#tableData_select option[value='${i}']`)[0]) {
+ // Add new option to list
+ let option = document.createElement("option");
+ option.value = `${i}`;
+ option.textContent = tableData[i].name;
+ $("#tableData_select")[0].insertBefore(
+ option, $("#tableData_select option[value='import']")[0]
+ );
+
+ let div = document.createElement("div");
+ div.id = `tableData_select-items-${i}`;
+ div.textContent = tableData[i].name;
+ div.addEventListener("click", tableData_option_onclick);
+ $(".tableData_select-items")[0].insertBefore(
+ div, $("#tableData_select-items-import")[0]
+ );
+ }
+ }
+
+ if (currentTableDataIndex === 0) {
+ // currentTableData is the initial object uploaded by user,
+ // modify the text of the existing "Current Year" option
+ $("#tableData_select option[value='0']")[0].textContent =
+ tableData[0].name;
+ $("#tableData_select-items-0")[0].textContent =
+ tableData[0].name;
+ }
+
+ $(`#tableData_select-items-${currentTableDataIndex}`).click();
+};
diff --git a/public/js/clock.js b/public/js/clock.js
index 5e7f6419..4e75c662 100755
--- a/public/js/clock.js
+++ b/public/js/clock.js
@@ -16,18 +16,27 @@ large_ctx.translate(large_radius, large_radius);
logo = document.getElementById("logo");
-let xhttp = new XMLHttpRequest;
-xhttp.onreadystatechange = function() {
- if (this.readyState === 4 && this.status === 200) {
- schedules = JSON.parse(this.responseText);
+let schedulesCallback = function(response) {
+ schedules = response;
+ redraw_clock();
+ setInterval(function() {
redraw_clock();
- setInterval(function() {
- redraw_clock();
- }, 1000);
- }
+ }, 1000);
};
-xhttp.open("GET", "schedule.json");
-xhttp.send();
+
+//#ifndef lite
+$.ajax({
+ url: "schedule.json",
+ method: "GET"
+}).then(schedulesCallback);
+//#endif
+//#ifdef lite
+/*
+schedulesCallback(
+//#include dist-lite/schedule.json
+);
+*/
+//#endif
function drawHand(ctx, radius, pos, length, width) {
ctx.strokeStyle = 'white';
@@ -128,22 +137,25 @@ function get_schedule(p3room, p3id) {
// Takes the default names (Period 1, etc) and overrides with real class
// names if they are available
function get_period_name(default_name) {
- if(typeof(tableData) === "undefined" || Object.keys(tableData).length === 0) {
- return default_name;
- }
- if (typeof(tableData.schedule) === "undefined" || Object.keys(tableData.schedule).length === 0) {
+ if (typeof(currentTableData) === "undefined"
+ || Object.keys(currentTableData).length === 0
+ || typeof(currentTableData.schedule) === "undefined"
+ || Object.keys(currentTableData.schedule).length === 0
+ || typeof(currentTableData.schedule.black) === "undefined"
+ || currentTableData.schedule.black.length === 0
+ ) {
return default_name;
}
if(period_names.black.length === 0) {
// set period_names -- should only be run once
- for(let i in tableData.schedule.black) {
- if(tableData.schedule.black[i].name !== "Community Meeting") {
- period_names.black.push(tableData.schedule.black[i]);
+ for(let i in currentTableData.schedule.black) {
+ if(currentTableData.schedule.black[i].name !== "Community Meeting") {
+ period_names.black.push(currentTableData.schedule.black[i]);
}
}
- for(let i in tableData.schedule.silver) {
- if(tableData.schedule.silver[i].name !== "Community Meeting") {
- period_names.silver.push(tableData.schedule.silver[i]);
+ for(let i in currentTableData.schedule.silver) {
+ if(currentTableData.schedule.silver[i].name !== "Community Meeting") {
+ period_names.silver.push(currentTableData.schedule.silver[i]);
}
}
// Guess lunch
diff --git a/public/js/extraFunctions.js b/public/js/extraFunctions.js
index 5799bf46..b9d739bb 100755
--- a/public/js/extraFunctions.js
+++ b/public/js/extraFunctions.js
@@ -43,7 +43,7 @@ function getGPA(gradeToBeGPA) {
function GPAType() {
let selectElem = $("#gpa_select");
- let selectedElem = $(".select-selected");
+ let selectedElem = $(".gpa_select-selected");
let selection = $("#gpa_select option")[selectElem.prop("selectedIndex")].value;
let quarterName = "";
@@ -51,24 +51,24 @@ function GPAType() {
if (selection == 0) {
quarterName = "Current Quarter";
- quarterData = tableData.terms.current;
+ quarterData = currentTableData.terms.current;
}
else {
quarterName = "Q" + selection;
- quarterData = tableData.terms["q" + selection];
+ quarterData = currentTableData.terms["q" + selection];
}
if (selectedElem.html().includes("GPA")) {
if (quarterData.GPA.outOfFour != quarterData.calcGPA.outOfFour) {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter Unweighted: " + tableData.terms.current.GPA.outOfFour.toFixed(2) +
- "
Calculated: " + tableData.terms.current.calcGPA.outOfFour.toFixed(2)
+ "Current Quarter Unweighted: " + currentTableData.terms.current.GPA.outOfFour.toFixed(2) +
+ "
Calculated: " + currentTableData.terms.current.calcGPA.outOfFour.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " Unweighted: " + tableData.terms["q" + i].GPA.outOfFour.toFixed(2) +
- (tableData.terms["q" + i].calcGPA ? (
- "
Calculated: " + tableData.terms["q" + i].calcGPA.outOfFour.toFixed(2)
+ "Q" + i + " Unweighted: " + currentTableData.terms["q" + i].GPA.outOfFour.toFixed(2) +
+ (currentTableData.terms["q" + i].calcGPA ? (
+ "
Calculated: " + currentTableData.terms["q" + i].calcGPA.outOfFour.toFixed(2)
) : "")
);
}
@@ -77,37 +77,37 @@ function GPAType() {
"
Calculated: " + quarterData.calcGPA.outOfFour.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative Unweighted: " + tableData.cumGPA.outOfFour.toFixed(2)
+ "Cumulative Unweighted: " + currentTableData.cumGPA.outOfFour.toFixed(2)
);
}
else {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter Unweighted: " + tableData.terms.current.GPA.outOfFour.toFixed(2)
+ "Current Quarter Unweighted: " + currentTableData.terms.current.GPA.outOfFour.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " Unweighted: " + tableData.terms["q" + i].GPA.outOfFour.toFixed(2)
+ "Q" + i + " Unweighted: " + currentTableData.terms["q" + i].GPA.outOfFour.toFixed(2)
);
}
selectedElem.html(
quarterName + " Unweighted: " + quarterData.GPA.outOfFour.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative Unweighted: " + tableData.cumGPA.outOfFour.toFixed(2)
+ "Cumulative Unweighted: " + currentTableData.cumGPA.outOfFour.toFixed(2)
);
}
}
else if (selectedElem.html().includes("Unweighted")) {
if (quarterData.GPA.outOfFive != quarterData.calcGPA.outOfFive) {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter Weighted: " + tableData.terms.current.GPA.outOfFive.toFixed(2) +
- "
Calculated: " + tableData.terms.current.calcGPA.outOfFive.toFixed(2)
+ "Current Quarter Weighted: " + currentTableData.terms.current.GPA.outOfFive.toFixed(2) +
+ "
Calculated: " + currentTableData.terms.current.calcGPA.outOfFive.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " Weighted: " + tableData.terms["q" + i].GPA.outOfFive.toFixed(2) +
- (tableData.terms["q" + i].calcGPA ? (
- "
Calculated: " + tableData.terms["q" + i].calcGPA.outOfFive.toFixed(2)
+ "Q" + i + " Weighted: " + currentTableData.terms["q" + i].GPA.outOfFive.toFixed(2) +
+ (currentTableData.terms["q" + i].calcGPA ? (
+ "
Calculated: " + currentTableData.terms["q" + i].calcGPA.outOfFive.toFixed(2)
) : "")
);
}
@@ -116,37 +116,37 @@ function GPAType() {
"
Calculated: " + quarterData.calcGPA.outOfFive.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative Weighted: " + tableData.cumGPA.outOfFive.toFixed(2)
+ "Cumulative Weighted: " + currentTableData.cumGPA.outOfFive.toFixed(2)
);
}
else {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter Weighted: " + tableData.terms.current.GPA.outOfFive.toFixed(2)
+ "Current Quarter Weighted: " + currentTableData.terms.current.GPA.outOfFive.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " Weighted: " + tableData.terms["q" + i].GPA.outOfFive.toFixed(2)
+ "Q" + i + " Weighted: " + currentTableData.terms["q" + i].GPA.outOfFive.toFixed(2)
);
}
selectedElem.html(
quarterName + " Weighted: " + quarterData.GPA.outOfFive.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative Weighted: " + tableData.cumGPA.outOfFive.toFixed(2)
+ "Cumulative Weighted: " + currentTableData.cumGPA.outOfFive.toFixed(2)
);
}
}
else if (selectedElem.html().includes("Weighted")) {
if (quarterData.GPA.percent != quarterData.calcGPA.percent) {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter GPA: " + tableData.terms.current.GPA.percent.toFixed(2) +
- "
Calculated: " + tableData.terms.current.calcGPA.percent.toFixed(2)
+ "Current Quarter GPA: " + currentTableData.terms.current.GPA.percent.toFixed(2) +
+ "
Calculated: " + currentTableData.terms.current.calcGPA.percent.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " GPA: " + tableData.terms["q" + i].GPA.percent.toFixed(2) +
- (tableData.terms["q" + i].calcGPA ? (
- "
Calculated: " + tableData.terms["q" + i].calcGPA.percent.toFixed(2)
+ "Q" + i + " GPA: " + currentTableData.terms["q" + i].GPA.percent.toFixed(2) +
+ (currentTableData.terms["q" + i].calcGPA ? (
+ "
Calculated: " + currentTableData.terms["q" + i].calcGPA.percent.toFixed(2)
) : "")
);
}
@@ -155,23 +155,23 @@ function GPAType() {
"
Calculated: " + quarterData.calcGPA.percent.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative GPA: " + tableData.cumGPA.percent.toFixed(2)
+ "Cumulative GPA: " + currentTableData.cumGPA.percent.toFixed(2)
);
}
else {
$("#current, #current_gpa, #init_gpa").html(
- "Current Quarter GPA: " + tableData.terms.current.GPA.percent.toFixed(2)
+ "Current Quarter GPA: " + currentTableData.terms.current.GPA.percent.toFixed(2)
);
for (let i = 1; i <= 4; i++) {
$(`#q${i}, #q${i}_gpa`).html(
- "Q" + i + " GPA: " + tableData.terms["q" + i].GPA.percent.toFixed(2)
+ "Q" + i + " GPA: " + currentTableData.terms["q" + i].GPA.percent.toFixed(2)
);
}
selectedElem.html(
quarterName + " GPA: " + quarterData.GPA.percent.toFixed(2)
);
$("#cum, #cum_gpa").html(
- "Cumulative GPA: " + tableData.cumGPA.percent.toFixed(2)
+ "Cumulative GPA: " + currentTableData.cumGPA.percent.toFixed(2)
);
}
}
@@ -209,7 +209,7 @@ function getLetterGrade(gradeToBeLettered) {
}
function getColor(gradeToBeColored) {
- if (vip_username_list.includes(tableData.username)) {
+ if (vip_username_list.includes(currentTableData.username)) {
return "#1E8541";
}
@@ -230,7 +230,7 @@ function getColor(gradeToBeColored) {
let lightColors = ["#3d995c", "#a3a3f5", "#eba947", "#ebb147", "#eb4747"];
function getLightColor(gradeToBeColored) {
- if (vip_username_list.includes(tableData.username)) {
+ if (vip_username_list.includes(currentTableData.username)) {
return "#1E8541";
}
@@ -253,7 +253,7 @@ let rowFormatter = function(cell) {
let rowColor = cell.getRow().getData().color;
let value = cell.getValue();
- if (vip_username_list.includes(tableData.username)) {
+ if (vip_username_list.includes(currentTableData.username)) {
return "
" + value + "";
}
@@ -276,7 +276,7 @@ let classColors = [
]
let classIndex = function(classname) {
- let classesArray = tableData.currentTermData.classes.map(x => x.name);
+ let classesArray = currentTableData.currentTermData.classes.map(x => x.name);
return (classesArray.indexOf(classname));
// why the mod 8?
}
@@ -286,7 +286,7 @@ let classFormatter = function(cell, formatterParams) {
let classColor = classColors[classIndex(rowClass)];
let value = cell.getValue();
- if (vip_username_list.includes(tableData.username)) {
+ if (vip_username_list.includes(currentTableData.username)) {
return "
" + value + "";
}
@@ -306,7 +306,7 @@ let weightFormatter = function(cell, formatterParams) {
value = value.substring(0, value.indexOf(".") + 2) + "%";
}
- if (vip_username_list.includes(tableData.username)) {
+ if (vip_username_list.includes(currentTableData.username)) {
return "
" + value + "";
}
@@ -329,7 +329,7 @@ let rowGradeFormatter = function(cell, formatterParams) {
} else {
let value = parseFloat(cell.getValue()) + "% " + getLetterGrade(cell.getValue());
- if (vip_username_list.includes(tableData.username)) {
+ if (vip_username_list.includes(currentTableData.username)) {
return "
" + value + "";
}
@@ -376,7 +376,7 @@ let gradeFormatter = function(cell, formatterParams) {
return "
" + real + "" + "
" + "
" + fake + "";
} else {
- if (vip_username_list.includes(tableData.username)) {
+ if (vip_username_list.includes(currentTableData.username)) {
return "
" + real + "" + "
" + "
" + fake + "";
}
@@ -452,7 +452,7 @@ let generate_pdf = function(index) {
$('#pdf-container').css('height', $(window).height() + 'px');
}
- let pdfInitParams = {"data": ((tableData.pdf_files)[index]).content};
+ let pdfInitParams = {"data": ((currentTableData.pdf_files)[index]).content};
// Store the index of the current PDF in `currentPdfIndex`
currentPdfIndex = index;
let loadingTask = pdfjsLib.getDocument(pdfInitParams);
@@ -469,7 +469,7 @@ let generate_pdf = function(index) {
let zoom_in_pdf = function() {
if (!pdfrendering) {
pdfrendering = true;
- let pdfInitParams = {"data": (tableData.pdf_files)[currentPdfIndex].content};
+ let pdfInitParams = {"data": (currentTableData.pdf_files)[currentPdfIndex].content};
let loadingTask = pdfjsLib.getDocument(pdfInitParams);
loadingTask.promise.then(function(pdf) {
@@ -507,7 +507,7 @@ let zoom_in_pdf = function() {
let zoom_out_pdf = function() {
if (!pdfrendering) {
pdfrendering = true;
- let pdfInitParams = {"data": (tableData.pdf_files)[currentPdfIndex].content};
+ let pdfInitParams = {"data": (currentTableData.pdf_files)[currentPdfIndex].content};
let loadingTask = pdfjsLib.getDocument(pdfInitParams);
loadingTask.promise.then(function(pdf) {
@@ -598,8 +598,8 @@ function closeAllSelect(elmnt) {
/* A function that will close all select boxes in the document,
except the current select box: */
let x, y, i, arrNo = [];
- x = document.getElementsByClassName("select-items");
- y = document.getElementsByClassName("select-selected");
+ x = document.getElementsByClassName("gpa_select-items");
+ y = document.getElementsByClassName("gpa_select-selected");
for (i = 0; i < y.length; i++) {
if (elmnt === y[i]) {
arrNo.push(i)
@@ -612,9 +612,35 @@ function closeAllSelect(elmnt) {
x[i].classList.add("select-hide");
}
}
- if (!$(".select-selected").hasClass("select-arrow-active")) {
- $('.select-selected').removeClass("activated-selected-item");
- $('.select-items div').removeClass("activated-select-items");
+ if (!$(".gpa_select-selected").hasClass("select-arrow-active")) {
+ $('.gpa_select-selected').removeClass("activated-selected-item");
+ $('.gpa_select-items div').removeClass("activated-select-items");
+ }
+
+}
+function tableData_closeAllSelect(elmnt) {
+ // $('.select-selected').removeClass("activated-selected-item");
+ $('.tableData_select-items div').removeClass("activated-select-items");
+ /* A function that will close all select boxes in the document,
+ except the current select box: */
+ let x, y, i, arrNo = [];
+ x = document.getElementsByClassName("tableData_select-items");
+ y = document.getElementsByClassName("tableData_select-selected");
+ for (i = 0; i < y.length; i++) {
+ if (elmnt === y[i]) {
+ arrNo.push(i)
+ } else {
+ y[i].classList.remove("select-arrow-active");
+ }
+ }
+ for (i = 0; i < x.length; i++) {
+ if (arrNo.indexOf(i)) {
+ x[i].classList.add("select-hide");
+ }
+ }
+ if (!$(".tableData_select-selected").hasClass("select-arrow-active")) {
+ $('.tableData_select-selected').removeClass("activated-selected-item");
+ $('.tableData_select-items div').removeClass("activated-select-items");
}
}
@@ -627,23 +653,23 @@ let initialize_pdf_dropdown = function() {
//$(o).html(tableData.pdf_files[i].title);
//$("#pdf-select").append(o);
- for (let i = 1; i < tableData.pdf_files.length + 1; i++) {
+ for (let i = 1; i < currentTableData.pdf_files.length + 1; i++) {
if (i === 1) {
- let o = new Option(tableData.pdf_files[i - 1].title, 0);
+ let o = new Option(currentTableData.pdf_files[i - 1].title, 0);
/// jquerify the DOM object 'o' so we can use the html method
- $(o).html(tableData.pdf_files[i - 1].title);
+ $(o).html(currentTableData.pdf_files[i - 1].title);
$("#pdf_select").append(o);
}
- let o = new Option(tableData.pdf_files[i - 1].title, i);
+ let o = new Option(currentTableData.pdf_files[i - 1].title, i);
/// jquerify the DOM object 'o' so we can use the html method
- $(o).html(tableData.pdf_files[i - 1].title);
+ $(o).html(currentTableData.pdf_files[i - 1].title);
$("#pdf_select").append(o);
}
let x, i, j, selElmnt, a, b, c;
- /* Look for any elements with the class "custom-select": */
+ /* Look for any elements with the class "pdf_custom-select": */
x = document.getElementsByClassName("pdf_custom-select");
for (i = 0; i < x.length; i++) {
selElmnt = x[i].getElementsByTagName("select")[0];
@@ -704,142 +730,275 @@ let initialize_pdf_dropdown = function() {
}
-let initialize_quarter_dropdown = function() {
+let listener = function(event) {
+ let _this = event.target;
+ /* When an item is clicked, update the original select box,
+ and the selected item: */
+
+ if (term_dropdown_active) {
+ let y, i, k, s, h;
+ s = _this.parentNode.parentNode.getElementsByTagName("select")[0];
+ h = _this.parentNode.previousSibling;
+ for (i = 0; i < s.length; i++) {
+ if (s.options[i].innerHTML === _this.innerHTML) {
+ if (i === 0) {
+ currentTerm = termConverter[i];
+ } else {
+ currentTerm = termConverter[i - 1];
+ }
+
+ if (i === 0) $("#mostRecentDiv").show();
+ else $("#mostRecentDiv").hide();
+
+ if (typeof currentTableData.terms[currentTerm].classes === 'undefined') {
+ // if (anyEdited()) {
+ // $(".gpa_select-selected").css('padding', "5px 16px 5px 16px");
+ // } else {
+ $(".gpa_select-selected").css("padding", "13px 16px 13px 16px");
+ // }
+
+ term_dropdown_active = false;
+
+ $.ajax({
+ url: "/data",
+ method: "POST",
+ data: { quarter: (i - 1) },
+ dataType: "json json",
+ success: responseCallbackPartial
+ });
+
+ $("#loader").show();
+ $("#classesTable").hide();
+ $("#assignmentsTable").hide(); //;.setData(tableData[i].assignments);
+ $("#categoriesTable").hide(); //;.setData(tableData[i].assignments);
+
+ s.selectedIndex = i;
+ h.innerHTML = this.innerHTML;
+ y = this.parentNode.getElementsByClassName("same-as-selected");
+ for (k = 0; k < y.length; k++) {
+ y[k].removeAttribute("class");
+ }
+ this.setAttribute("class", "same-as-selected");
+ break;
+
+ } else {
+ if (anyEdited()) {
+ $(".gpa_select-selected").css('padding', "5px 16px 5px 16px");
+ } else {
+ $(".gpa_select-selected").css("padding", "13px 16px 13px 16px");
+ }
+
+ if (i === 0) {
+ currentTableData.currentTermData = currentTableData.terms.current;
+ } else {
+ currentTableData.currentTermData = currentTableData.terms["q" + (i - 1)];
+ }
+
+ classesTable.setData(currentTableData.currentTermData.classes);
+
+ $("#assignmentsTable").hide(); //;.setData(tableData[i].assignments);
+ $("#categoriesTable").hide(); //;.setData(tableData[i].assignments);
+ selected_class_i = undefined;
+ //categoriesTable.setData(tableData[i].categoryDisplay);
+
+ s.selectedIndex = i;
+ h.innerHTML = this.innerHTML;
+ y = this.parentNode.getElementsByClassName("same-as-selected");
+ for (k = 0; k < y.length; k++) {
+ y[k].removeAttribute("class");
+ }
+ this.setAttribute("class", "same-as-selected");
+ break;
+ }
+ }
+ }
+ h.click();
+ } else {
+ console.log("Term dropdown not active");
+ }
+};
+
+/*
+ * includedTerms is an optional parameter which contains the terms
+ * included in an import (in the case that currentTableData is imported
+ * and not all of the terms' data have been put into currentTableData)
+ */
+let initialize_quarter_dropdown = function(includedTerms) {
+ /* Look for any elements with the class "gpa_custom-select": */
+ let x = document.getElementsByClassName("gpa_custom-select")[0];
+ let selElmnt = x.getElementsByTagName("select")[0];
+ /* For each element, create a new DIV that will act as the selected item: */
+ let a;
+ if (!(a = document.getElementsByClassName("gpa_select-selected")[0])) {
+ a = document.createElement("DIV");
+ a.setAttribute("class", "gpa_select-selected select-selected");
+ x.appendChild(a);
+ a.addEventListener("click", function(e) {
+ /* When the select box is clicked, close any other select boxes,
+ and open/close the current select box: */
+ e.stopPropagation();
+ closeAllSelect(this);
+ this.nextSibling.classList.toggle("select-hide");
+ this.classList.toggle("select-arrow-active");
+ $('.gpa_select-selected').toggleClass("activated-selected-item");
+ $('.gpa_select-items div').toggleClass("activated-select-items");
+ //resetTableData();
+ });
+ }
+ a.innerHTML = selElmnt.options[selElmnt.selectedIndex].innerHTML;
+
+ /* For each element, create a new DIV that will contain the option list: */
+ let b;
+ if (!(b = document.getElementById("view_gpa_select"))) {
+ b = document.createElement("DIV");
+ b.setAttribute("class", "gpa_select-items select-items select-hide");
+ b.setAttribute("id", "view_gpa_select");
+ x.appendChild(b);
+ }
+
+ for (let j = 1; j < selElmnt.length; j++) {
+ /* For each option in the original select element,
+ create a new DIV that will act as an option item: */
+ let c;
+ if (!(c = document.getElementById(termConverter[j - 1] || "cum"))) {
+ c = document.createElement("DIV");
+ c.innerHTML = selElmnt.options[j].innerHTML;
+ c.id = termConverter[j - 1] || "cum";
+ }
+ const term = termConverter[parseInt(c.innerHTML[1]) || 0];
+ const isAccessibleObj = isAccessible(term, includedTerms);
+ $(c)
+ .removeClass(["inaccessible", "hastooltip"])
+ .removeAttr("aria-label")
+ .removeAttr("tabindex");
+ c.removeEventListener("click", listener);
+
+ if (isAccessibleObj.accessible) {
+ c.addEventListener("click", listener);
+ }
+ else {
+ $(c)
+ .addClass(["inaccessible", "hastooltip"])
+ .attr("aria-label", isAccessibleObj.reason)
+ .attr("tabindex", 0);
+ }
+
+ b.appendChild(c);
+ }
+};
+
+let setup_quarter_dropdown = function() {
+ $(".gpa_select-selected").html("Current Quarter GPA: " + currentTableData.currentTermData.GPA.percent);
+ $("#current").html("Current Quarter GPA: " + currentTableData.currentTermData.GPA.percent);
+ document.getElementById('gpa_select').options[0].innerHTML = "Current Quarter GPA: " + currentTableData.currentTermData.GPA.percent;
+ document.getElementById('gpa_select').options[1].innerHTML = "Current Quarter GPA: " + currentTableData.currentTermData.GPA.percent;
+
+ $(".gpa_select-items").children().each(function(i, elem) {
+ if (i < 5) {//Don't try to get quarter data for the 5th element in the list because that's not a quarter...
+ if (i === 0) {
+ $(this).html("Current Quarter GPA: " + currentTableData.terms["current"].GPA.percent);
+ document.getElementById('gpa_select').options[0].innerHTML = "Current Quarter GPA: " + currentTableData.terms["current"].GPA.percent;
+ document.getElementById('gpa_select').options[1].innerHTML = "Current Quarter GPA: " + currentTableData.terms["current"].GPA.percent;
+ } else {
+ if (!isNaN(currentTableData.terms["q" + i].GPA.percent)) {
+ $(this).html("Q" + i + " GPA: " + currentTableData.terms["q" + i].GPA.percent);
+ document.getElementById('gpa_select').options[i + 1].innerHTML ="Q" + i + " GPA: " + currentTableData.terms["q" + i].GPA.percent;
+ } else {
+ $(this).html("Q" + i + " GPA: None");
+ document.getElementById('gpa_select').options[i + 1].innerHTML ="Q" + i + " GPA: None";
+ }
+ }
+ }
+ });
+};
+
+let tableData_option_onclick = function() {
+ if (this.id === "tableData_select-items-import") {
+ showModal("import");
+ return;
+ }
+
+ let index_temp = parseInt(this.id.substring("tableData_select-items-".length))
+ currentTableDataIndex =
+ isNaN(index_temp) ? currentTableDataIndex : index_temp;
+ currentTableData = tableData[currentTableDataIndex];
+
+ /* When an item is clicked, update the original select box,
+ and the selected item: */
+ let y, i, k, s, h;
+ s = this.parentNode.parentNode.getElementsByTagName("select")[0];
+ h = this.parentNode.previousSibling;
+ for (i = 0; i < s.length; i++) {
+ if (s.options[i].innerHTML === this.innerHTML) {
+ s.selectedIndex = i;
+ h.innerHTML = this.innerHTML;
+ y = this.parentNode.getElementsByClassName("tableData_same-as-selected");
+ for (k = 0; k < y.length; k++) {
+ y[k].removeAttribute("class");
+ }
+ this.setAttribute("class", "tableData_same-as-selected");
+ break;
+ }
+ }
+
+ // Re-initialize the quarter dropdown with the data from
+ // currentTableData
+ initialize_quarter_dropdown()
+ setup_quarter_dropdown();
+
+ classesTable.setData(currentTableData.currentTermData.classes);
+ scheduleTable.setData(currentTableData.schedule.black);
+
+ // Reset clock
+ period_names = {black:[], silver:[]};
+
+ // Hide Reports tab for imported data
+ if (currentTableData.imported) {
+ $("#reports_open").hide();
+ }
+ else {
+ $("#reports_open").show();
+ }
+ h.click();
+}
+
+let initialize_tableData_dropdown = function() {
let x, i, j, selElmnt, a, b, c;
- /* Look for any elements with the class "custom-select": */
- x = document.getElementsByClassName("custom-select");
+ /* Look for any elements with the class "pdf_custom-select": */
+ x = document.getElementsByClassName("tableData_custom-select");
for (i = 0; i < x.length; i++) {
selElmnt = x[i].getElementsByTagName("select")[0];
/* For each element, create a new DIV that will act as the selected item: */
a = document.createElement("DIV");
- a.setAttribute("class", "select-selected");
+ a.setAttribute("class", "tableData_select-selected select-selected");
a.innerHTML = selElmnt.options[selElmnt.selectedIndex].innerHTML;
x[i].appendChild(a);
/* For each element, create a new DIV that will contain the option list: */
b = document.createElement("DIV");
- b.setAttribute("class", "select-items select-hide");
- b.setAttribute("id", "view_gpa_select");
+ b.setAttribute("class", "tableData_select-items select-items select-hide");
for (j = 1; j < selElmnt.length; j++) {
/* For each option in the original select element,
create a new DIV that will act as an option item: */
c = document.createElement("DIV");
+ c.id = `tableData_select-items-${selElmnt.options[j].value}`;
c.innerHTML = selElmnt.options[j].innerHTML;
- c.id = termConverter[j - 1] || "cum";
- // if (!isNaN(tableData.terms[termConverter[j - 1]].GPA.percent)) {
- c.addEventListener("click", function(e) {
- if (!this.innerHTML.includes("N")) {
- /* When an item is clicked, update the original select box,
- and the selected item: */
-
- if (term_dropdown_active) {
- let y, i, k, s, h;
- s = this.parentNode.parentNode.getElementsByTagName("select")[0];
- h = this.parentNode.previousSibling;
- for (i = 0; i < s.length; i++) {
- if (s.options[i].innerHTML === this.innerHTML) {
- if (i === 0) {
- currentTerm = termConverter[i];
- } else {
- currentTerm = termConverter[i - 1];
- }
-
-
- if (i === 0) $("#mostRecentDiv").show();
- else $("#mostRecentDiv").hide();
-
-
- if (typeof tableData.terms[currentTerm].classes === 'undefined') {
- // if (anyEdited()) {
- // $(".select-selected").css('padding', "5px 16px 5px 16px");
- // } else {
- $(".select-selected").css("padding", "13px 16px 13px 16px");
- // }
-
-
- term_dropdown_active = false;
-
- $.ajax({
- url: "/data",
- method: "POST",
- data: { quarter: (i - 1) },
- dataType: "json json",
- success: responseCallbackPartial
- });
-
- $("#loader").show();
- $("#classesTable").hide();
- $("#assignmentsTable").hide(); //;.setData(tableData[i].assignments);
- $("#categoriesTable").hide(); //;.setData(tableData[i].assignments);
-
- s.selectedIndex = i;
- h.innerHTML = this.innerHTML;
- y = this.parentNode.getElementsByClassName("same-as-selected");
- for (k = 0; k < y.length; k++) {
- y[k].removeAttribute("class");
- }
- this.setAttribute("class", "same-as-selected");
- break;
-
-
-
- } else {
-
- if (anyEdited()) {
- $(".select-selected").css('padding', "5px 16px 5px 16px");
- } else {
- $(".select-selected").css("padding", "13px 16px 13px 16px");
- }
-
- if (i === 0) {
- tableData.currentTermData = tableData.terms.current;
- } else {
- tableData.currentTermData = tableData.terms["q" + (i - 1)];
- }
-
- classesTable.setData(tableData.currentTermData.classes);
-
- $("#assignmentsTable").hide(); //;.setData(tableData[i].assignments);
- $("#categoriesTable").hide(); //;.setData(tableData[i].assignments);
- selected_class_i = undefined;
- //categoriesTable.setData(tableData[i].categoryDisplay);
-
- s.selectedIndex = i;
- h.innerHTML = this.innerHTML;
- y = this.parentNode.getElementsByClassName("same-as-selected");
- for (k = 0; k < y.length; k++) {
- y[k].removeAttribute("class");
- }
- this.setAttribute("class", "same-as-selected");
- break;
- }
- }
- }
- h.click();
- } else {
- console.log("Term dropdown not active");
- }
- }
- });
+ c.addEventListener("click", tableData_option_onclick);
b.appendChild(c);
}
x[i].appendChild(b);
a.addEventListener("click", function(e) {
- //$('.select-selected').addClass("activated-select-items");
- //$('.select-items div').addClass("activated-select-items");
/* When the select box is clicked, close any other select boxes,
and open/close the current select box: */
-
e.stopPropagation();
- closeAllSelect(this);
+ //pdf_closeAllSelect(this);
this.nextSibling.classList.toggle("select-hide");
this.classList.toggle("select-arrow-active");
- $('.select-selected').toggleClass("activated-selected-item");
- $('.select-items div').toggleClass("activated-select-items");
- //resetTableData();
+ $('.tableData_select-selected').toggleClass("activated-selected-item");
+ $('.tableData_select-items div').toggleClass("activated-select-items");
});
}
-};
+}
let toggle_fullscreen_pdf = function() {
let elem = document.getElementById('reports');
@@ -958,9 +1117,9 @@ function parseTableData(classes) {
classes[i].color = getColor(classes[i].calculated_grade);
}
}
- tableData.currentTermData.classes = classes;
- let GPA = computeGPA(tableData.currentTermData.classes);
- let calcGPA = computeGPA(tableData.currentTermData.classes);
+ currentTableData.currentTermData.classes = classes;
+ let GPA = computeGPA(currentTableData.currentTermData.classes);
+ let calcGPA = computeGPA(currentTableData.currentTermData.classes);
return {
classes,
GPA,
@@ -968,7 +1127,7 @@ function parseTableData(classes) {
};
}
let anyEdited = function() {
- let termsEdited = (tableData.terms[currentTerm].classes).map(function(currentValue, index, array) {
+ let termsEdited = (currentTableData.terms[currentTerm].classes).map(function(currentValue, index, array) {
return currentValue.edited
});
let finalDecision = false;
@@ -980,3 +1139,43 @@ let anyEdited = function() {
return finalDecision;
}
+/*
+ * Returns an object containing whether or not a term is 'accessible',
+ * and if not, a reason for inaccessibility.
+ * A term is accessible if its data are available in currentTableData
+ * or can be retrieved from Aspen.
+ *
+ * includedTerms is an optional parameter which contains the terms
+ * included in an import (in the case that currentTableData is imported
+ * and not all of the terms' data have been put into currentTableData)
+ */
+let isAccessible = function(term, includedTerms) {
+ // Boolean storing whether or not this term is 'accessible'
+ let accessible = true;
+ // Reason for term being inaccessible
+ let reason = "";
+ // If no GPA is available for the term, it is inaccessible
+ // (the term was not included in Aspen's overview)
+ if (!currentTableData.terms[term].GPA.percent) {
+ accessible = false;
+ reason = "This term is not available on Aspen.";
+ }
+ // If currentTableData is imported, we cannot scrape Aspen
+ // for more data, so any terms not included in the import
+ // are inaccessible
+ if (
+ currentTableData.imported &&
+ (
+ (includedTerms && !includedTerms[term]) ||
+ !currentTableData.terms[term].classes
+ )
+ ) {
+ accessible = false;
+ reason = "This term is not included in the imported data.";
+ }
+
+ return {
+ accessible: accessible,
+ reason: reason
+ };
+}
diff --git a/public/js/home.js b/public/js/home.js
index fd672b01..3dfee8a1 100644
--- a/public/js/home.js
+++ b/public/js/home.js
@@ -1,20 +1,36 @@
const termConverter = ['current', 'q1', 'q2', 'q3', 'q4'];
let pdf_index = 0;
let pdfrendering = false;
+let modals = {
+ "stats": document.getElementById('stats_modal'),
+ "export": document.getElementById('export_modal'),
+ "import": document.getElementById('import_modal')
+};
let statsModal = document.getElementById('stats_modal');
+let exportModal = document.getElementById('export_modal');
+let importModal = document.getElementById('import_modal');
let term_dropdown_active = true;
let currentTerm = "current";
-let tableData = {};
+let tableData = [{ name: "Current Year" }];
+let currentTableDataIndex = 0;
+let currentTableData = tableData[currentTableDataIndex];
let selected_class_i;
let termsReset = {};
-// When the user clicks anywhere outside of the modal, close it
+// When the user clicks anywhere outside of a modal or dropdown, close it
window.addEventListener("click", function(event) {
- if (event.target === statsModal) {
- hideModal();
+ Object.keys(modals).forEach(key => {
+ if (event.target === modals[key]) {
+ hideModal(key);
+ }
+ });
+ // Do not close a dropdown if the user clicked to view a tooltip
+ // (e.g. on a mobile device)
+ if (!event.target.classList.contains("hastooltip")) {
+ closeAllSelect();
+ pdf_closeAllSelect();
+ tableData_closeAllSelect();
}
- pdf_closeAllSelect();
- closeAllSelect();
});
window.getStats = async function(session_id, apache_token, assignment_id) {
@@ -53,10 +69,6 @@ window.addEventListener('resize', function() {
}
});
*/
-let hideModal = function() {
- document.getElementById('stats_modal').style.display = "none";
- noStats();
-}
let noStats = function() {
$("#there_are_stats").hide();
$("#there_are_no_stats").show();
@@ -65,6 +77,15 @@ let noStats = function() {
document.getElementById("stats_modal_content").style.height = "80px";
//document.getElementById("stats_modal_content").style.margin = "300px auto";
document.getElementById("stats_modal_content").style.top = "140px";
+};
+
+let hideModal = function(key) {
+ modals[key].style.display = "none";
+ if (key === "stats") noStats();
+}
+
+let showModal = function(key) {
+ modals[key].style.display = "inline-block";
}
let recentAttendance = new Tabulator("#recentAttendance", {
@@ -140,7 +161,7 @@ let categoriesTable = new Tabulator("#categoriesTable", {
//{title: "", width:1, align:"center", headerSort: false},
{
title: "Hide",
- titleFormatter: () => '
',
+ titleFormatter: () => '',
headerClick: hideCategoriesTable,
width: 76,
headerSort: false
@@ -230,17 +251,17 @@ let assignmentsTable = new Tabulator("#assignmentsTable", {
for (
let k = 0;
k < Object.keys(
- tableData.currentTermData.classes[selected_class_i].categories
+ currentTableData.currentTermData.classes[selected_class_i].categories
).length;
k++
) {
catCategories.push((
Object.keys(
- tableData.currentTermData.classes[selected_class_i].categories
+ currentTableData.currentTermData.classes[selected_class_i].categories
)[k] + " (" +
(
Object.values(
- tableData.currentTermData.classes[selected_class_i].categories
+ currentTableData.currentTermData.classes[selected_class_i].categories
)[k] * 100
) + "%)"
));
@@ -285,7 +306,7 @@ let assignmentsTable = new Tabulator("#assignmentsTable", {
noStats();
document.getElementById("no_stats_caption").innerHTML = "Loading Statistics...";
//document.getElementById("stats_modal_title").innerHTML = "";
- document.getElementById('stats_modal').style.display = "inline-block";
+ showModal("stats");
//$("#there_are_stats").hide();
//$("#there_are_no_stats").show();
//document.getElementById("stats_modal_caption").style.top = "7px";
@@ -293,8 +314,8 @@ let assignmentsTable = new Tabulator("#assignmentsTable", {
//document.getElementById("stats_modal_content").style.margin = "300px auto";
//document.getElementById("stats_modal_content").style.top = "140px";
- let session_id = tableData.currentTermData.classes[selected_class_i].tokens.session_id;
- let apache_token = tableData.currentTermData.classes[selected_class_i].tokens.apache_token;
+ let session_id = currentTableData.currentTermData.classes[selected_class_i].tokens.session_id;
+ let apache_token = currentTableData.currentTermData.classes[selected_class_i].tokens.apache_token;
let assignment_id = cell.getRow().getData().assignment_id;
let assignment = cell.getRow().getData().name;
let score = cell.getRow().getData().score;
@@ -527,7 +548,7 @@ let classesTable = new Tabulator("#classesTable", {
let rowColor = cell.getRow().getData().color;
let value = cell.getValue();
- if (vip_username_list.includes(tableData.username)) {
+ if (vip_username_list.includes(currentTableData.username)) {
return "
" + value + "";
}
if (rowColor === "black") {
@@ -546,8 +567,36 @@ let classesTable = new Tabulator("#classesTable", {
headerSort: false,
},
{
- title: "Hide",
- titleFormatter: () => '
',
+ title: "Export Table Data",
+ titleFormatter: () => '',
+ headerClick: async () => {
+ // Disable checkboxes for inaccessible terms
+ termConverter.forEach(term => {
+ let isAccessibleObj = isAccessible(term);
+
+ if (isAccessibleObj.accessible) {
+ $(`#export_checkbox_terms_${term}`).removeAttr("disabled");
+ $(`#export_checkbox_terms_${term} ~ span`)
+ .removeAttr("aria-label")
+ .removeAttr("tabindex")
+ .removeClass("hastooltip");
+ }
+ else {
+ $(`#export_checkbox_terms_${term}`) .attr("disabled", true);
+ $(`#export_checkbox_terms_${term} ~ span`)
+ .attr("aria-label", isAccessibleObj.reason)
+ .attr("tabindex", 0)
+ .addClass("hastooltip");
+ }
+ });
+ exportModal.style.display = "inline-block";
+ },
+ width: 76,
+ headerSort: false,
+ },
+ {
+ title: "Reset Table Data",
+ titleFormatter: () => '',
headerClick: resetTableData,
width: 76,
headerSort: false,
@@ -571,9 +620,26 @@ let classesTable = new Tabulator("#classesTable", {
},
});
-// Callback for response from /data
-function responseCallback(response) {
+/*
+ * Callback for response from /data
+ *
+ * includedTerms is an optional parameter which contains the terms
+ * included in an import (in the case that currentTableData is imported
+ * and not all of the terms' data have been put into currentTableData)
+ */
+function responseCallback(response, includedTerms) {
// console.log(response);
+ if (response.nologin) {
+ tableData = [];
+ currentTableData = undefined;
+ currentTableDataIndex = -1;
+
+ $("#reports_open").hide();
+ $("#loader").hide();
+
+ showModal("import");
+ return;
+ }
if (response.recent.login_fail) {
location.href='/logout';
}
@@ -610,22 +676,23 @@ function responseCallback(response) {
}];
}
- if (typeof tableData !== 'undefined') {
- tableData.recent = response.recent;
- tableData.overview = response.overview;
- tableData.username = response.username;
+ if (typeof tableData[currentTableDataIndex] !== 'undefined') {
+ currentTableData.recent = response.recent;
+ currentTableData.overview = response.overview;
+ currentTableData.username = response.username;
} else {
- tableData = {};
- tableData.recent = response.recent;
- tableData.overview = response.overview;
- tableData.username = response.username;
+ tableData[currentTableDataIndex] = {};
+ currentTableData = tableData[currentTableDataIndex];
+ currentTableData.recent = response.recent;
+ currentTableData.overview = response.overview;
+ currentTableData.username = response.username;
}
$("#loader").hide();
//parsing the data extracted by the scrappers, and getting tableData ready for presentation
- if (typeof tableData.terms === 'undefined') {
- tableData.terms = {
+ if (typeof currentTableData.terms === 'undefined') {
+ currentTableData.terms = {
current: {},
q1: {},
q2: {},
@@ -634,49 +701,49 @@ function responseCallback(response) {
};
}
- if (typeof tableData.currentTermData === 'undefined') {
- tableData.currentTermData = {};
+ if (typeof currentTableData.currentTermData === 'undefined') {
+ currentTableData.currentTermData = {};
}
- tableData.currentTermData = parseTableData(response.classes);
- tableData.terms[currentTerm] = parseTableData(response.classes);
+ currentTableData.currentTermData = parseTableData(response.classes);
+ currentTableData.terms[currentTerm] = parseTableData(response.classes);
//populates the event for each row in the recentAttendance table
- for (let i = 0; i < tableData.recent.recentAttendanceArray.length; i++) {
- tableData.recent.recentAttendanceArray[i].event = "";
- if (tableData.recent.recentAttendanceArray[i].dismissed === "true") {
- tableData.recent.recentAttendanceArray[i].event += "Dismissed ";
+ for (let i = 0; i < currentTableData.recent.recentAttendanceArray.length; i++) {
+ currentTableData.recent.recentAttendanceArray[i].event = "";
+ if (currentTableData.recent.recentAttendanceArray[i].dismissed === "true") {
+ currentTableData.recent.recentAttendanceArray[i].event += "Dismissed ";
}
- if (tableData.recent.recentAttendanceArray[i].excused === "true") {
- tableData.recent.recentAttendanceArray[i].event += "Excused ";
+ if (currentTableData.recent.recentAttendanceArray[i].excused === "true") {
+ currentTableData.recent.recentAttendanceArray[i].event += "Excused ";
}
- if (tableData.recent.recentAttendanceArray[i].absent === "true") {
- tableData.recent.recentAttendanceArray[i].event += "Absent ";
+ if (currentTableData.recent.recentAttendanceArray[i].absent === "true") {
+ currentTableData.recent.recentAttendanceArray[i].event += "Absent ";
}
- if (tableData.recent.recentAttendanceArray[i].tardy === "true") {
- tableData.recent.recentAttendanceArray[i].event += "Tardy ";
+ if (currentTableData.recent.recentAttendanceArray[i].tardy === "true") {
+ currentTableData.recent.recentAttendanceArray[i].event += "Tardy ";
}
}
- let activityArray = tableData.recent.recentActivityArray.slice();
+ let activityArray = currentTableData.recent.recentActivityArray.slice();
for (let i = 0; i < activityArray.length; i++) {
try {
let assignmentName = activityArray[i].assignment;
let className = activityArray[i].classname;
let temp_classIndex = classIndex(className);
- let assignmentIndex = tableData.currentTermData
+ let assignmentIndex = currentTableData.currentTermData
.classes[temp_classIndex].assignments.map(x => x.name)
.indexOf(assignmentName);
console.log(assignmentIndex);
- tableData.recent.recentActivityArray[i].assignmentName = assignmentName;
- tableData.recent.recentActivityArray[i].className = className;
- tableData.recent.recentActivityArray[i].temp_classIndex = temp_classIndex;
- tableData.recent.recentActivityArray[i].assignmentIndex = assignmentIndex;
+ currentTableData.recent.recentActivityArray[i].assignmentName = assignmentName;
+ currentTableData.recent.recentActivityArray[i].className = className;
+ currentTableData.recent.recentActivityArray[i].temp_classIndex = temp_classIndex;
+ currentTableData.recent.recentActivityArray[i].assignmentIndex = assignmentIndex;
- tableData.recent.recentActivityArray[i].max_score = tableData.currentTermData.classes[temp_classIndex].assignments[assignmentIndex].max_score;
- tableData.recent.recentActivityArray[i].percentage = tableData.currentTermData.classes[temp_classIndex].assignments[assignmentIndex].percentage;
- tableData.recent.recentActivityArray[i].color = tableData.currentTermData.classes[temp_classIndex].assignments[assignmentIndex].color;
+ currentTableData.recent.recentActivityArray[i].max_score = currentTableData.currentTermData.classes[temp_classIndex].assignments[assignmentIndex].max_score;
+ currentTableData.recent.recentActivityArray[i].percentage = currentTableData.currentTermData.classes[temp_classIndex].assignments[assignmentIndex].percentage;
+ currentTableData.recent.recentActivityArray[i].color = currentTableData.currentTermData.classes[temp_classIndex].assignments[assignmentIndex].color;
}
catch(err) {
console.log("Please report this error on the Aspine github issue pages. ID Number 101. Error: " + err);
@@ -684,52 +751,36 @@ function responseCallback(response) {
}
// Calculate GPA for current term
- tableData.terms.current.GPA = computeGPA(tableData.terms.current.classes);
+ currentTableData.terms.current.GPA = response.GPA ||
+ computeGPA(currentTableData.terms.current.classes);
- tableData.overview = response.overview;
+ currentTableData.overview = response.overview;
- tableData.cumGPA = cumGPA(tableData.overview);
- document.getElementById("cum_gpa").innerHTML = "Cumulative GPA: " + tableData.cumGPA.percent.toFixed(2);
+ currentTableData.cumGPA = response.cumGPA || cumGPA(currentTableData.overview);
+ document.getElementById("cum_gpa").innerHTML = "Cumulative GPA: " + currentTableData.cumGPA.percent.toFixed(2);
// Calculate GPA for each quarter
for (let i = 1; i <= 4; i++) {
- tableData.terms["q" + i].GPA = computeGPAQuarter(tableData.overview,i);
+ currentTableData.terms["q" + i].GPA = computeGPAQuarter(currentTableData.overview,i);
}
//Stuff to do now that tableData is initialized
$("#mostRecentDiv").show();
- mostRecentTable.setData(tableData.recent.recentActivityArray.slice(0, 5));
-
- initialize_quarter_dropdown();
- termsReset[currentTerm] = JSON.parse(JSON.stringify(tableData.terms[currentTerm]));
-
- $(".select-selected").html("Current Quarter GPA: " + tableData.currentTermData.GPA.percent);
- $("#current").html("Current Quarter GPA: " + tableData.currentTermData.GPA.percent);
- document.getElementById('gpa_select').options[0].innerHTML = "Current Quarter GPA: " + tableData.currentTermData.GPA.percent;
- document.getElementById('gpa_select').options[1].innerHTML = "Current Quarter GPA: " + tableData.currentTermData.GPA.percent;
-
- $(".select-items").children().each(function(i, elem) {
- if (i < 5) {//Don't try to get quarter data for the 5th element in the list because that's not a quarter...
- if (i === 0) {
- $(this).html("Current Quarter GPA: " + tableData.terms["current"].GPA.percent);
- document.getElementById('gpa_select').options[0].innerHTML = "Current Quarter GPA: " + tableData.terms["current"].GPA.percent;
- document.getElementById('gpa_select').options[1].innerHTML = "Current Quarter GPA: " + tableData.terms["current"].GPA.percent;
- } else {
- if (!isNaN(tableData.terms["q" + i].GPA.percent)) {
- $(this).html("Q" + i + " GPA: " + tableData.terms["q" + i].GPA.percent);
- document.getElementById('gpa_select').options[i + 1].innerHTML ="Q" + i + " GPA: " + tableData.terms["q" + i].GPA.percent;
- } else {
- $(this).html("Q" + i + " GPA: None");
- document.getElementById('gpa_select').options[i + 1].innerHTML ="Q" + i + " GPA: None";
- }
- }
- }
- });
+ mostRecentTable.setData(currentTableData.recent.recentActivityArray.slice(0, 5));
+
+ initialize_quarter_dropdown(includedTerms);
+ setup_quarter_dropdown();
+
+ termsReset[currentTerm] = JSON.parse(JSON.stringify(currentTableData.terms[currentTerm]));
+
+ if (!$(".tableData_select-selected")[0]) {
+ initialize_tableData_dropdown();
+ }
// scheduleTable.setData(tableData.schedule.black);
- recentActivity.setData(tableData.recent.recentActivityArray);
- recentAttendance.setData(tableData.recent.recentAttendanceArray);
+ recentActivity.setData(currentTableData.recent.recentActivityArray);
+ recentAttendance.setData(currentTableData.recent.recentAttendanceArray);
classesTable.setData(response.classes); //set data of classes table to the tableData property of the response json object
@@ -745,47 +796,47 @@ function responseCallback(response) {
function responseCallbackPartial(response) {
$("#loader").hide();
- tableData.currentTermData = tableData.terms[currentTerm];
+ currentTableData.currentTermData = currentTableData.terms[currentTerm];
let temp_term_data = parseTableData(response.classes);
- tableData.terms[currentTerm].classes = temp_term_data.classes;
- tableData.terms[currentTerm].GPA = temp_term_data.GPA;
- tableData.terms[currentTerm].calcGPA = temp_term_data.calcGPA;
+ currentTableData.terms[currentTerm].classes = temp_term_data.classes;
+ currentTableData.terms[currentTerm].GPA = temp_term_data.GPA;
+ currentTableData.terms[currentTerm].calcGPA = temp_term_data.calcGPA;
/*
if (currentTerm === 'current') {
- $(".select-selected").html("Current Quarter GPA: " + tableData.currentTermData.GPA.percent);
+ $(".gpa_select-selected").html("Current Quarter GPA: " + tableData.currentTermData.GPA.percent);
$("#current").html("Current Quarter GPA: " + tableData.currentTermData.GPA.percent);
document.getElementById('gpa_select').options[0].innerHTML = "Current Quarter GPA: " + tableData.currentTermData.GPA.percent;
document.getElementById('gpa_select').options[1].innerHTML = "Current Quarter GPA: " + tableData.currentTermData.GPA.percent;
} else {
- $(".select-selected").html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + tableData.currentTermData.GPA.percent);
+ $(".gpa_select-selected").html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + tableData.currentTermData.GPA.percent);
$("#q" + termConverter.indexOf(currentTerm)).html("Q" + termConverter.indexOf(currentTerm) + " GPA: " + tableData.currentTermData.GPA.percent);
document.getElementById('gpa_select').options[termConverter.indexOf(currentTerm) + 1].innerHTML ="Q" + termConverter.indexOf(currentTerm) + " GPA: " + tableData.currentTermData.GPA.percent;
}
*/
- scheduleTable.setData(tableData.schedule.black);
+ scheduleTable.setData(currentTableData.schedule.black);
$("#classesTable").show();
classesTable.setData(response.classes); //set data of classes table to the tableData property of the response json object
classesTable.redraw();
- termsReset[currentTerm] = JSON.parse(JSON.stringify(tableData.terms[currentTerm]));
+ termsReset[currentTerm] = JSON.parse(JSON.stringify(currentTableData.terms[currentTerm]));
term_dropdown_active = true;
}
// Callback for response from /schedule
function scheduleCallback(response) {
- if (!tableData.schedule) tableData.schedule = response;
+ if (!currentTableData.schedule) currentTableData.schedule = response;
document.getElementById("scheduleTable").style.rowBackgroundColor = "black";
//the following lines are used to set up the schedule table correctly
//let periods = ["Period 1", "CM/OTI", "Period 2", "Period 3", "Period 4"];
- let periods = tableData.schedule.black.slice().map(x => x.aspenPeriod.substring(x.aspenPeriod.indexOf("-") + 1));
+ let periods = currentTableData.schedule.black.slice().map(x => x.aspenPeriod.substring(x.aspenPeriod.indexOf("-") + 1));
let placeTimes = ["8:05 - 9:25", "9:29 - 9:44", "9:48 - 11:08", "11:12 - 1:06", "1:10 - 2:30"];
let timesCounter = 0;
let times = [];
@@ -804,43 +855,35 @@ function scheduleCallback(response) {
let colors = ["#63C082", "#72C68E", "#82CC9B", "#91D2A7", "#A1D9B4", "#B1DFC0", "#C0E5CD", "#D0ECD9"];
for (let i = 0; i < periods.length; i++) {
- if (tableData.schedule.black[i]) {
- tableData.schedule.black[i].period = periods[i] ? periods[i] + "
" + times[i] : "Extra";
- tableData.schedule.black[i].class = tableData.schedule.black[i].name + "
" + tableData.schedule.black[i].teacher;
- tableData.schedule.black[i].color = colors[i] ? colors[i] : colors[colors.length - 1];
+ if (currentTableData.schedule.black[i]) {
+ currentTableData.schedule.black[i].period = periods[i] ? periods[i] + "
" + times[i] : "Extra";
+ currentTableData.schedule.black[i].class = currentTableData.schedule.black[i].name + "
" + currentTableData.schedule.black[i].teacher;
+ currentTableData.schedule.black[i].color = colors[i] ? colors[i] : colors[colors.length - 1];
}
- if (tableData.schedule.silver[i]) {
- tableData.schedule.silver[i].period = periods[i] ? periods[i] + "
" + times[i] : "Extra";
- tableData.schedule.silver[i].class = tableData.schedule.silver[i].name + "
" + tableData.schedule.silver[i].teacher;
- tableData.schedule.silver[i].color = colors[colors.length - 1 - i] ? colors[colors.length - 1 - i] : colors[0];
+ if (currentTableData.schedule.silver[i]) {
+ currentTableData.schedule.silver[i].period = periods[i] ? periods[i] + "
" + times[i] : "Extra";
+ currentTableData.schedule.silver[i].class = currentTableData.schedule.silver[i].name + "
" + currentTableData.schedule.silver[i].teacher;
+ currentTableData.schedule.silver[i].color = colors[colors.length - 1 - i] ? colors[colors.length - 1 - i] : colors[0];
}
}
- scheduleTable.setData(tableData.schedule.black);
+ scheduleTable.setData(currentTableData.schedule.black);
redraw_clock();
}
function pdfCallback(response) {
$("#loader").hide();
// console.log(response);
- tableData.pdf_files = response;
+ currentTableData.pdf_files = response;
initialize_pdf_dropdown();
$("#pdf_loading_text").hide();
- if (typeof tableData.pdf_files !== 'undefined') {
+ if (typeof currentTableData.pdf_files !== 'undefined') {
generate_pdf(pdf_index);
}
}
-$.ajax({
- url: "/data",
- method: "POST",
- data: { quarter: 0 },
- dataType: "json json",
- success: responseCallback
-});
-
function recent_toggle() {
if (!document.getElementById("recent_toggle").checked) {
//recentActivity.setData(tableData.recent.recentActivityArray);
@@ -859,11 +902,11 @@ function recent_toggle() {
function schedule_toggle() {
if (document.getElementById("schedule_toggle").checked) {
- scheduleTable.setData(tableData.schedule.silver);
+ scheduleTable.setData(currentTableData.schedule.silver);
document.getElementById("schedule_title").innerHTML = "Silver";
redraw_clock();
} else {
- scheduleTable.setData(tableData.schedule.black);
+ scheduleTable.setData(currentTableData.schedule.black);
document.getElementById("schedule_title").innerHTML = "Black";
redraw_clock();
}
@@ -903,7 +946,7 @@ function openTab(evt, tab_name) {
}
if (tab_name === "reports") {
- if (!tableData.pdf_files) {
+ if (!currentTableData.pdf_files) {
$("#loader").show();
$.ajax({
url: "/pdf",
@@ -912,7 +955,7 @@ function openTab(evt, tab_name) {
success: pdfCallback
});
}
- else if (typeof tableData.pdf_files !== 'undefined') {
+ else if (typeof currentTableData.pdf_files !== 'undefined') {
generate_pdf(pdf_index);
}
// Redraw PDF to fit new viewport dimensions when transitioning
@@ -933,7 +976,7 @@ function openTab(evt, tab_name) {
}
}
- if (tab_name === "schedule" && !tableData.schedule) {
+ if (tab_name === "schedule" && !currentTableData.schedule) {
$.ajax({
url: "/schedule",
method: "POST",
@@ -950,9 +993,73 @@ function openTab(evt, tab_name) {
recentAttendance.redraw();
}
+$("#export_button").click(() => {
+ prefs = {};
+
+ [
+ "recent", "schedule", "cumGPA"
+ ].forEach(pref => {
+ prefs[pref] = $(`#export_checkbox_${pref}`).prop("checked");
+ });
+
+ if ($("#export_checkbox_terms").prop("checked")) {
+ prefs.terms = {};
+ termConverter.forEach(term => {
+ if (
+ !$(`#export_checkbox_terms_${term}`).prop("disabled") &&
+ $(`#export_checkbox_terms_${term}`).prop("checked")
+ ) prefs.terms[term] = true;
+ else prefs.terms[term] = false;
+ });
+ }
+
+ exportTableData(prefs);
+});
+
+$("#import_button").click(async () => {
+ const file = document.getElementById("import_filepicker").files[0];
+ const reader = new FileReader();
+ reader.readAsText(file);
+ reader.addEventListener("load", async () => {
+ let obj = JSON.parse(reader.result);
+ obj.name = file.name;
+ let response = await importTableData(obj) || "";
+ $("#import_error").html(response);
+ if (!response) {
+ hideModal("import");
+ }
+ });
+});
+
+//#ifndef lite
+$.ajax({
+ url: "/data",
+ method: "POST",
+ data: { quarter: 0 },
+ dataType: "json json",
+}).then(responseCallback);
+//#endif
+
+//#ifdef lite
+/*
+responseCallback({ nologin: true });
+*/
+//#endif
+
document.getElementById("default_open").click();
// Populate the version number at the bottom of the page.
// Pointfree style does not work here because jQuery's .text behaves both as
// an attribute and as a function.
+
+//#ifndef lite
$.ajax("/version").then(ver => $("#version").text(ver));
+//#endif
+
+//#ifdef lite
+/*
+$("#version").text(
+//#include $version
+);
+*/
+//#endif
diff --git a/public/login.html b/public/login.html
index 17dbf102..f3b5aec3 100755
--- a/public/login.html
+++ b/public/login.html
@@ -55,7 +55,7 @@
- *Use Aspen™ Credentials
+ Use Aspen credentials or leave blank to import data
diff --git a/serve.js b/serve.js
index 0ea55512..8ac72776 100644
--- a/serve.js
+++ b/serve.js
@@ -19,15 +19,12 @@ const child_process = require('child_process');
// -------------------------------------------
if (args.hasOwnProperty('help') || args._.includes('help')) {
- console.log(`Usage: ./serve.js [insecure] [fake] [OPTION]...
+ console.log(`Usage: ./serve.js [OPTION]...
Starts the Aspine web server.
Options:
- --fake use file "public/sample2.json" instead of scraping Aspen
- --insecure do not use SSL/TLS (HTTPS)
- --json=FILE use JSON file FILE instead of scraping Aspen
- --out=FILE scrape Aspen as usual but dump JSON to file FILE
- --help display this help and exit
+ --insecure do not secure connections with TLS (HTTPS)
+ --help display this help and exit
`);
process.exit();
}
@@ -117,6 +114,14 @@ new Map([
'/vendor/pdf.js/pdf.worker.min.js',
'/node_modules/pdfjs-dist/build/pdf.worker.min.js'
],
+ [
+ '/vendor/file-saver/FileSaver.min.js',
+ '/node_modules/file-saver/dist/FileSaver.min.js'
+ ],
+ [
+ '/vendor/file-saver/FileSaver.min.js.map',
+ '/node_modules/file-saver/dist/FileSaver.min.js.map'
+ ],
[
'/fonts/fontawesome/css/all.min.css',
'/node_modules/@fortawesome/fontawesome-free/css/all.min.css'
@@ -133,7 +138,10 @@ app.use('/fonts/fontawesome/webfonts', express.static(
// Endpoint to expose version number to client
app.get('/version', async (req, res) => {
child_process.exec('git describe',
- (error, stdout, stderr) => res.send(stdout.trim())
+ (error, stdout, stderr) => res.send(
+ // Trim 'v' from version number
+ stdout.trim().match(/^v?(.*)/)[1]
+ )
);
});
@@ -142,6 +150,10 @@ app.use(function(req, res, next) { // enable cors
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
+
+app.get('/home.html', (req, res) => res.redirect('/'));
+app.get('/login.html', (req, res) => res.redirect('/login'));
+
app.use(express.static('public')); // Serve any files in public directory
app.use(bodyParser.urlencoded({ extended: true })); // Allows form submission
app.use(bodyParser.json()); // json parser
@@ -155,15 +167,7 @@ app.use(session({
app.post('/stats', async (req, res) => {
console.log(`\n\nNEW STATS REQUEST: ${req.body.session_id}, ${req.body.apache_token}, ${req.body.assignment_id} \n------------------`);
- if(!(args.hasOwnProperty("fake") || args._.includes("fake"))) {
- // USE REAL DATA:
- res.send(await scraper.scrape_assignmentDetails(req.body.session_id, req.body.apache_token, req.body.assignment_id));
- } else {
- //USE FAKE DATA:
- res.send(await scraper.scrape_assignmentDetails(req.body.session_id, req.body.apache_token, req.body.assignment_id));
- //res.send("Hello World");
- //res.sendFile('sample.json', {root:"public"});
- }
+ res.send(await scraper.scrape_assignmentDetails(req.body.session_id, req.body.apache_token, req.body.assignment_id));
});
app.post('/data', async (req, res) => {
@@ -173,35 +177,18 @@ app.post('/data', async (req, res) => {
// if (err) throw err;
// });
- if (args.hasOwnProperty("json")) {
- // Check if "--json" command-line argument was provided, e.g.
- // node serve.js --json=./public/sample.json
-
- // Use json file provided at command line
- res.sendFile(args.json, {root: "."});
- }
let response;
- if (args._.includes("fake")) {
- // For backwards compatibility
-
- res.sendFile('sample2.json', {root: "public"});
- } else {
- //res.send(await scraper.scrape_student(req.session.username, req.session.password));
- //
- // Get data from scraper:
- //
- response = await scraper.scrape_student(req.session.username, req.session.password, req.body.quarter);
- res.send(response);
-
- // If "out" command-line argument provided, save JSON at the given path
- if (args.hasOwnProperty("out")) {
- fs.writeFile(
- args.out, JSON.stringify(response),
- (err) => {
- if (err) throw err;
- }
- );
- }
+ //res.send(await scraper.scrape_student(req.session.username, req.session.password));
+ //
+ // Get data from scraper:
+ //
+ if (req.session.nologin) {
+ res.send({ nologin: true });
+ }
+ else {
+ res.send(await scraper.scrape_student(
+ req.session.username, req.session.password, req.body.quarter
+ ));
}
});
@@ -214,17 +201,24 @@ app.post('/pdf', async (req, res) => {
});
app.get('/', async (req, res) => {
- if(typeof(req.session) != "undefined") {
- res.redirect('/home.html');
+ if (req.session.username || req.session.nologin) {
+ res.sendFile(__dirname + '/public/home.html');
} else {
res.redirect('/login.html');
}
});
+app.get('/login', (req, res) => res.sendFile(__dirname + '/public/login.html'));
+
app.post('/login', async (req, res) => {
- req.session.username = req.body.username;
- req.session.password = req.body.password;
- res.redirect('/home.html');
+ if (req.body.username && req.body.password) {
+ req.session.username = req.body.username;
+ req.session.password = req.body.password;
+ }
+ else {
+ req.session.nologin = true;
+ }
+ res.redirect('/home.html');
});
app.get('/logout', async (req, res) => {