Compare commits

...

2 Commits

4 changed files with 131 additions and 13 deletions

View File

@ -117,20 +117,54 @@ async function cloneSchedule(includeAssignments) {
}
document.getElementById('cloneSch').addEventListener('click', async e => {
cloneSchedule(true);
await cloneSchedule(true);
});
document.getElementById('cloneSchNoAssignments').addEventListener('click', async e => {
cloneSchedule(false);
await cloneSchedule(false);
});
const titleInput = document.getElementById('title');
const schStartTime = document.getElementById('sch_start_time')
const schEndTime = document.getElementById('sch_end_time')
const schGranularity = document.getElementById('granularity')
let allowEdits = false;
async function updateScheduleSettings() {
await updateBackupsList();
titleInput.value = schedule.base_title;
titleInput.disabled = !allowEdits;
schStartTime.value = schedule.start_time.inputValue;
schEndTime.value = schedule.end_time.inputValue;
schGranularity.value = schedule.granularity.inputValue;
const daysSpan = document.getElementById('sch-days');
utils.clearChildren(daysSpan);
for (const day of utils.allDays) {
const dayLabel = document.createElement('label');
const dayName = utils.DayString(day);
const dayCheckbox = document.createElement('input');
dayCheckbox.type = 'checkbox';
dayCheckbox.checked = schedule.all_days.includes(day);
dayCheckbox.addEventListener('change', async e => {
if (!e.target.checked) {
if (schedule.assignments.some(a => day in a.people_by_day)) {
alert("Cannot remove schedule for " + dayName
+ " because there are events on that day.");
e.target.checked = true;
return;
}
schedule.all_days.splice(schedule.all_days.indexOf(day), 1);
} else {
schedule.all_days = utils.allDays.filter(d => schedule.all_days.includes(d) || d === day)
}
await saveSchedule();
});
dayLabel.appendChild(dayCheckbox);
dayLabel.appendChild(document.createTextNode(dayName));
daysSpan.appendChild(dayLabel);
}
document.getElementById('scheduleMetadata')
.querySelectorAll('*')
@ -292,6 +326,52 @@ document.getElementById('changeTitle').addEventListener('click', async e => {
await saveSchedule();
});
schStartTime.addEventListener('change', async e => {
const newStartTime = utils.Time.fromInputValue(e.target.value);
if (schedule.assignments) {
const earliestStart = schedule.assignments.map(a => a.start_time).sort((a, b) => a.cmp(b))[0];
if (earliestStart.cmp(newStartTime) < 0) {
alert("Cannot change start time to " + newStartTime.to12HourString()
+ " because it is after the earliest assignment starts at "
+ earliestStart.to12HourString() + ".");
return;
}
}
schedule.start_time = newStartTime;
await saveSchedule();
});
schEndTime.addEventListener('change', async e => {
const newEndTime = utils.Time.fromInputValue(e.target.value);
if (schedule.assignments) {
const latestEnd = schedule.assignments.map(a => a.end_time).sort((a, b) => b.cmp(a))[0];
if (latestEnd.cmp(newEndTime) > 0) {
alert("Cannot change end time to " + newEndTime.to12HourString()
+ " because it is before the latest assignment ends at "
+ latestEnd.to12HourString() + ".");
return;
}
}
schedule.end_time = newEndTime;
await saveSchedule();
});
schGranularity.addEventListener('change', async e => {
const newGranularity = utils.Time.fromInputValue(e.target.value)
.durationSinceMidnight;
const schDuration = schedule.timeRange.duration;
const newNumRows = schDuration.dividedBy(newGranularity);
if (!Number.isInteger(newNumRows)) {
alert("Cannot change granularity to " + newGranularity.toString()
+ " because it is does not divide the " + schDuration.toString()
+ " duration from " + schedule.start_time.to12HourString()
+ " to " + schedule.end_time.to12HourString() + ".");
return;
}
schedule.granularity = newGranularity;
await saveSchedule();
});
const personInput = document.getElementById('person');
document.getElementById('addStudent').addEventListener('click', async e => {

View File

@ -39,6 +39,10 @@
<div id="scheduleMetadata">
<label>Title: <input id="title"></label>
<button id="changeTitle">Change Title</button><br>
<label>Start time: <input type="time" id="sch_start_time"></label><br>
<label>End time: <input type="time" id="sch_end_time"></label><br>
<label>Granularity: <input type="time" id="granularity"></label><br>
Days: <span id="sch-days"></span><br>
<label>Name: <input id="person"></label>
<button id="addTeacher">Add Teacher</button>
<button id="addStaff">Add Staff</button>

View File

@ -57,6 +57,10 @@ export default class Schedule {
}
}
get timeRange() {
return new utils.TimeRange(this);
}
fullGridFor(day) {
function timestampString(date) {
function f(format) {

View File

@ -57,10 +57,17 @@ export class Time {
export class Duration {
constructor(obj) {
this.hour = obj.hour ?? 0;
this.minute = obj.minute ?? 0;
this.second = obj.second ?? 0;
this.total_seconds = ((this.hour * 60) + this.minute) * 60 + this.second;
if (obj.total_seconds) {
this.total_seconds = obj.total_seconds;
this.hour = Math.floor(obj.total_seconds / 60 / 60);
this.minute = Math.floor(obj.total_seconds / 60) % 60;
this.second = obj.total_seconds % 60;
} else {
this.hour = obj.hour ?? 0;
this.minute = obj.minute ?? 0;
this.second = obj.second ?? 0;
this.total_seconds = ((this.hour * 60) + this.minute) * 60 + this.second;
}
}
asJsonObject() {
@ -82,6 +89,25 @@ export class Duration {
const hour = Math.floor(total / 60 / 60);
return new Duration({hour, minute, second});
}
toString() {
let res = "";
if (this.hour) {
res += this.hour + (this.hour === 1 ? " hour" : " hours ");
}
if (this.minute) {
res += this.minute + (this.minute === 1 ? " minute" : " minutes ");
}
if (this.second) {
res += this.second + (this.second === 1 ? " second" : " seconds");
}
return this.total_seconds === 0 ? "0 seconds" : res.trimEnd();
}
get inputValue() {
return new Time({}).plus(this).inputValue;
}
}
export class TimeRange {
@ -92,9 +118,9 @@ export class TimeRange {
get duration() {
return new Duration({
'hour': this.end_time.hour - this.start_time.hour,
'minute': this.end_time.minute - this.start_time.minute,
'second': this.end_time.second - this.start_time.second,
'total_seconds': 60 * 60 * (this.end_time.hour - this.start_time.hour)
+ 60 * (this.end_time.minute - this.start_time.minute)
+ this.end_time.second - this.start_time.second,
});
}
@ -106,8 +132,7 @@ export class TimeRange {
}
}
export function DayString(day) {
return {
const dayDictionary = {
'M': 'Monday',
'T': 'Tuesday',
'W': 'Wednesday',
@ -115,9 +140,14 @@ export function DayString(day) {
'F': 'Friday',
'S': 'Saturday',
'U': 'Sunday',
}[day];
};
export function DayString(day) {
return dayDictionary[day];
}
export const allDays = Object.keys(dayDictionary);
export function clearChildren(el) {
while (el.firstChild) el.removeChild(el.lastChild);
}