aboutsummaryrefslogtreecommitdiff
path: root/js/graduation-common.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/graduation-common.js')
-rw-r--r--js/graduation-common.js161
1 files changed, 132 insertions, 29 deletions
diff --git a/js/graduation-common.js b/js/graduation-common.js
index 3ab1fdd..1c68f38 100644
--- a/js/graduation-common.js
+++ b/js/graduation-common.js
@@ -22,11 +22,15 @@ class GraduationChange {
publicDBFields () {
return {
"change": this.change,
+ "date": this.date,
};
}
dbFields () {
return {
+ // We include the date in the json because Moodle reports the timeadded
+ // locale dependent.
+ "date": this.date,
"change": this.change,
"reason": this.reason,
"context": this.context,
@@ -34,9 +38,25 @@ class GraduationChange {
}
static fromDBEntry(e) {
- const {date, coach, json} = e;
+ const {coach, json} = e;
const change = JSON.parse(json);
- return new GraduationChange(new Date(date), change.change, change.reason, coach, change.context);
+ return new GraduationChange(new Date(change.date), change.change, change.reason, coach, change.context);
+ }
+
+ static newObservationRequest() {
+ return new GraduationChange(new Date(), "ObservationRequest", "", "", "");
+ }
+
+ static newObservationStart() {
+ return new GraduationChange(new Date(), "ObservationStart", "", "", "");
+ }
+
+ static newObservationEnd(reason, success) {
+ return new GraduationChange(new Date(), "ObservationEnd", reason, "", JSON.stringify(success));
+ }
+
+ static newObservationChange(observation) {
+ return new GraduationChange(observation.date, "Observation", "", "", JSON.stringify(observation.status));
}
static newGreenPointChange(reason, coach) {
@@ -53,14 +73,16 @@ class GraduationChange {
}
class Graduation {
- constructor(student, green, orange, red, level, stickers, observation, changes) {
+ constructor(student, green, orange, red, level, stickers, observationRequested, observation, pastObservations, changes) {
this.student = student;
this.green = green;
this.orange = orange;
this.red = red;
this.level = level;
this.stickers = stickers;
+ this.observationRequested = observationRequested;
this.observation = observation;
+ this.pastObservations = pastObservations;
this.changes = changes;
student.graduation = this;
@@ -71,41 +93,66 @@ class Graduation {
let orange = 0;
let red = 0;
let level = 1;
+ let openObservationRequest = null;
let observationPeriod = null;
let pastObservations = [];
let stickers = [];
+
+ // The parsing logic assumes that changes are ordered chronologically
+ changes.sort((a, b) => a.date - b.date);
+
for (const change of changes) {
switch (change.change) {
case "GrĂ¼n":
green++;
break;
+
case "Orange":
orange++;
break;
+
case "Rot":
red++;
break;
+
+ case "ObservationRequest":
+ openObservationRequest = change.date;
+ break;
+
case "ObservationStart":
- observationPeriod = new ObservationPeriod(change.date, null, []);
+ console.assert(openObservationRequest, "No request for observation start");
+ observationPeriod = new ObservationPeriod(change.date);
+ openObservationRequest = null;
break;
+
case "ObservationEnd":
- observationPeriod.end = change.date;
+ console.assert(observationPeriod, "No active observation period");
+ observationPeriod.finishPeriod(change.context.success);
+ if (change.context.success) {
+ level++;
+ }
pastObservations.push(observationPeriod);
observationPeriod = null;
break;
+
case "Observation":
- const observation = Observation.fromContext(change.context);
- if (observationPeriod) {
- observationPeriod.addObservation(observation);
- } else {
- alert(`No active observation period`);
- }
+ console.assert(observationPeriod, "No active observation period");
+ const observation = Observation.fromChange(change);
+ observationPeriod.addObservation(observation);
+ break;
+
+ case "LevelChange":
+ level = change.context.level;
break;
+
default:
alert(`Unexpected change: ${change}`);
}
}
- return new Graduation(student, green, orange, red, level, stickers, observationPeriod, changes);
+ return new Graduation(student, green, orange, red, level,
+ stickers,
+ openObservationRequest, observationPeriod, pastObservations,
+ changes);
}
addChange(change) {
@@ -120,7 +167,36 @@ class Graduation {
* Request observation
*/
async requestObservation() {
- await addEntryToStudentDatabase(this.student, "submit", {change: "ObservationRequest"});
+ const request = GraduationChange.newObservationRequest();
+ this.observationRequested = request.date;
+ await addEntryToStudentDatabase(this.student, "submit", JSON.stringify(request.publicDBFields()));
+ }
+
+ /**
+ * Start an observation
+ */
+ async startObservation() {
+ if (!this.observationRequested) {
+ console.assert(this.observationRequested, "No observation requested");
+ return;
+ }
+ this.observationRequested = null;
+ this.observation = new ObservationPeriod(new Date());
+ return submitGraduationChange(this.student, GraduationChange.newObservationStart());
+ }
+
+ /**
+ * End an observation
+ */
+ async endObservation(reason, success) {
+ if (!this.observation) {
+ console.assert(this.observation, "No active observation");
+ return;
+ }
+ this.observation.end = new Date();
+ this.pastObservations.push(this.observation);
+ this.observation = null;
+ return submitGraduationChange(this.student, GraduationChange.newObservationEnd(reason, success));
}
/**
@@ -147,10 +223,14 @@ class Graduation {
}
class ObservationPeriod {
- constructor(start, end, observations) {
+ constructor(start) {
this.start = start;
- this.end = end;
- this.observations = observations;
+ this.observations = [];
+ }
+
+ finishPeriod(success) {
+ this.end = new Date();
+ this.success = success;
}
ended() {
@@ -158,18 +238,28 @@ class ObservationPeriod {
}
ready() {
- // TODO(muhq): add time contraint
- return this.observations > 10;
+ if (this.observations.length < 10)
+ return false;
+
+ // at least 10 observation on different days
+ let days = new Map();
+ for (const observation of this.observations) {
+ const d = observation.date;
+ days.set(`${d.getFullYear()}${d.getMonth()}${d.getDate()}`, true);
+ }
+ return days.size >= 10;
}
getObservationsSums() {
- let sums = Array(OBSERVATION_TYPES.length).fill({"yes":0, "no":0});
+ let sums = Array(OBSERVATION_TYPES.length).fill().map(() => ({"yes":0, "no":0}));
for (const observation of this.observations) {
for (let i = 0; i < sums.length; i++) {
- if (observation.status[i])
- sums[i].yes++;
- else
- sums[i].no++;
+ if (observation.status[i]) {
+ if (observation.status[i] === "yes")
+ sums[i].yes++;
+ else
+ sums[i].no++;
+ }
}
}
return sums;
@@ -192,10 +282,14 @@ const OBSERVATION_TYPES = [
class Observation {
constructor(date, status) {
- console.assert(status.length != OBSERVATION_TYPES.length, "invalid observation status");
+ console.assert(status.length == OBSERVATION_TYPES.length, "invalid observation status");
this.date = date;
this.status = status;
}
+
+ static fromChange(change) {
+ return new Observation(change.date, JSON.parse(change.context))
+ }
}
async function fetchGraduationChangesFromDb(student, type) {
@@ -206,15 +300,23 @@ async function fetchGraduationChangesFromDb(student, type) {
const gradChange = GraduationChange.fromDBEntry(e);
changes.push(gradChange);
}
- return changes;
+ return changes.flat();
}
async function fetchGraduationChanges(student) {
- return fetchGraduationChangesFromDb(student, "shadow");
+ let changes = await Promise.all([
+ fetchGraduationChangesFromDb(student, "shadow"),
+ fetchGraduationChangesFromDb(student, "submit"),
+ ]);
+ return changes.flat();
}
async function fetchPublicGraduationChanges(student) {
- return fetchGraduationChangesFromDb(student, "public");
+ let changes = await Promise.all([
+ fetchGraduationChangesFromDb(student, "public"),
+ fetchGraduationChangesFromDb(student, "submit"),
+ ]);
+ return changes.flat();
}
async function fetchGraduation(student) {
@@ -248,8 +350,9 @@ async function submitGraduationChange(student, change) {
}
async function submitObservation(student, observation) {
- student.graduation.addObservation(observation);
- await addEntryToStudentDatabase(student, "shadow", JSON.stringify(observation));
+ console.assert(student.graduation.observation, "no active observation");
+ student.graduation.observation.addObservation(observation);
+ await submitGraduationChange(student, GraduationChange.newObservationChange(observation));
}
export {