schedule-grid-js/www/schedule.js

128 lines
4.0 KiB
JavaScript

import Assignment from './assignment.js';
import ScheduleGrid from './scheduleGrid.js';
import * as utils from './utils.js';
export default class Schedule {
constructor(obj) {
this.base_title = obj.title;
this.assignments = obj.assignments.map(a => new Assignment(a));
// TODO Custom day names? Schedules might not be weekly.
this.all_days = obj.all_days;
// TODO Remove hard-coded participant kinds.
this.all_students = obj.all_students ?? [];
this.all_staff = obj.all_staff ?? [];
this.all_teachers = obj.all_teachers ?? [];
this.granularity = obj.granularity !== undefined
? new utils.Duration(obj.granularity)
: new utils.Duration({minute: 10});
this.start_time = new utils.Time(obj.start_time);
this.end_time = new utils.Time(obj.end_time);
this.people_info = obj.people_info;
this.lastModified = obj.lastModified ?? new Date();
for (const teacher of this.all_teachers) {
if (!this.all_staff.includes(teacher)) {
this.all_staff.push(teacher);
}
}
this.all_students.sort();
this.all_staff.sort();
this.all_teachers.sort();
this.recomputeNotAssigned();
}
recomputeNotAssigned() {
this.assignedStaff = new Set(this.assignments.flatMap(a => [...a.all_staff]));
this.assignedStudents = new Set(this.assignments.flatMap(a => [...a.all_students]));
this.notAssignedStaff = utils.setDifference(this.all_staff, this.assignedStaff);
this.notAssignedStudents = utils.setDifference(this.all_students, this.assignedStudents);
}
asJsonObject() {
return {
'title': this.base_title,
'assignments': this.assignments.map(a => a.asJsonObject()),
// TODO Custom day names? Schedules might not be weekly.
'all_days': this.all_days,
// TODO Remove hard-coded participant kinds.
'all_students': this.all_students,
'all_staff': this.all_staff,
'all_teachers': this.all_teachers,
'granularity': this.granularity.asJsonObject(),
'start_time': this.start_time.asJsonObject(),
'end_time': this.end_time.asJsonObject(),
'people_info': this.people_info,
}
}
get timeRange() {
return new utils.TimeRange(this);
}
fullGridFor(day) {
function timestampString(date) {
function f(format) {
return new Intl.DateTimeFormat('en', format).format(date);
}
return f({month: 'short'}) + ' ' + f({day: 'numeric'}) + ' '
+ f({timeStyle: 'short'});
}
return new ScheduleGrid({
'title': this.base_title + ' ' + utils.DayString(day) + ' schedule ['
+ timestampString(this.lastModified) + ']',
'granularity': this.granularity,
'start_time': this.start_time,
'end_time': this.end_time,
'single_column': false,
'events': this.assignments
.filter(a => a.days.includes(day))
.map(a => a.asEvent(day, this.granularity, false)),
})
}
addStudent(name) {
if (this.all_students.includes(name)) return false;
this.all_students.push(name);
this.all_students.sort();
this.notAssignedStudents.add(name);
}
addStaff(name) {
if (this.all_staff.includes(name)) return false;
this.all_staff.push(name);
this.all_staff.sort();
this.notAssignedStaff.add(name);
}
addTeacher(name) {
if (!this.addStaff(name)) return false;
this.all_teachers.push(name);
this.all_teachers.sort();
this.notAssignedStaff.add(name);
}
delStaff(name) {
if (!this.notAssignedStaff.has(name)) {
throw "Tried to remove staff " + name + " who has assignments.";
}
this.notAssignedStaff.delete(name);
this.all_staff.splice(this.all_staff.indexOf(name), 1);
const teacherIdx = this.all_teachers.indexOf(name);
if (teacherIdx > -1) this.all_teachers.splice(teacherIdx, 1);
}
delStudent(name) {
if (!this.notAssignedStudents.has(name)) {
throw "Tried to remove student " + name + " who has assignments.";
}
this.notAssignedStudents.delete(name);
this.all_students.splice(this.all_students.indexOf(name), 1);
}
}