Compare commits
2 Commits
25d50c9385
...
e97a42973d
Author | SHA1 | Date | |
---|---|---|---|
e97a42973d | |||
3692ebfd88 |
110
www/app.js
110
www/app.js
|
@ -9,9 +9,35 @@ import * as utils from './utils.js';
|
||||||
const openDirButton = document.getElementById('openDir');
|
const openDirButton = document.getElementById('openDir');
|
||||||
const reopenDirButton = document.getElementById('reopenDir');
|
const reopenDirButton = document.getElementById('reopenDir');
|
||||||
const closeDirButton = document.getElementById('closeDir');
|
const closeDirButton = document.getElementById('closeDir');
|
||||||
|
|
||||||
|
const importButton = document.getElementById('import');
|
||||||
|
const importFileInput = document.getElementById('importFile');
|
||||||
|
const exportButton = document.getElementById('export');
|
||||||
|
|
||||||
const schedulesDiv = document.getElementById('allSchedules');
|
const schedulesDiv = document.getElementById('allSchedules');
|
||||||
const scheduleSettingsDiv = document.getElementById('scheduleSettings');
|
const scheduleSettingsDiv = document.getElementById('scheduleSettings');
|
||||||
|
|
||||||
|
const displaySettingsDiv = document.getElementById('displaySettings');
|
||||||
|
const displayDays = document.getElementById('displayDays');
|
||||||
|
const displayPeople = document.getElementById('displayPeople');
|
||||||
|
|
||||||
|
const assignmentFormDiv = document.getElementById('assignmentFormDiv');
|
||||||
|
const assignmentForm = document.getElementById('assignmentForm');
|
||||||
|
const assignmentSelector = assignmentForm.assignments;
|
||||||
|
const peopleTable = document.getElementById('peopleTable');
|
||||||
|
|
||||||
|
let peopleCheckboxes = undefined;
|
||||||
|
let selectedAssignment = undefined;
|
||||||
|
|
||||||
|
const personInfoDiv = document.getElementById('personInfo');
|
||||||
|
const personStartTime = document.getElementById('person_start_time');
|
||||||
|
const personEndTime = document.getElementById('person_end_time');
|
||||||
|
const personDays = document.getElementById('person_days');
|
||||||
|
|
||||||
|
const warningsSection = document.getElementById('warningsSection');
|
||||||
|
const warningsDiv = document.getElementById('warnings');
|
||||||
|
|
||||||
|
|
||||||
let dirHandle = null;
|
let dirHandle = null;
|
||||||
let backupsDir = null;
|
let backupsDir = null;
|
||||||
let fileHandle = null;
|
let fileHandle = null;
|
||||||
|
@ -145,6 +171,64 @@ document.getElementById('restoreBackup').addEventListener('click', async e => {
|
||||||
restoreBackup();
|
restoreBackup();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function download(filename, text, mimeType) {
|
||||||
|
const element = document.createElement('a');
|
||||||
|
element.setAttribute('href', 'data:' + mimeType + ',' + encodeURIComponent(text));
|
||||||
|
element.setAttribute('download', filename);
|
||||||
|
|
||||||
|
element.style.display = 'none';
|
||||||
|
document.body.appendChild(element);
|
||||||
|
|
||||||
|
element.click();
|
||||||
|
|
||||||
|
document.body.removeChild(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function exportToFile() {
|
||||||
|
const name = basefileHandle.name.slice(0, -5);
|
||||||
|
const dateName = new Date().toISOString().replaceAll(':', '-');
|
||||||
|
download(name + '-' + dateName + '.json',
|
||||||
|
JSON.stringify(schedule.asJsonObject(), null, 2),
|
||||||
|
'application/json');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function importFromFile() {
|
||||||
|
const fileList = importFileInput.files;
|
||||||
|
const file = fileList[0];
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
if (hash.backup) {
|
||||||
|
// swap back to base file...
|
||||||
|
await loadFile(basefileHandle, false);
|
||||||
|
}
|
||||||
|
// ... create a new backup...
|
||||||
|
await createBackup(true);
|
||||||
|
|
||||||
|
reader.onload = async (e) => {
|
||||||
|
const json = e.target.result;
|
||||||
|
|
||||||
|
schedule = new Schedule(JSON.parse(json));
|
||||||
|
schedule.lastModified = file.lastModified;
|
||||||
|
|
||||||
|
await saveSchedule();
|
||||||
|
await loadFile(basefileHandle, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.readAsText(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
exportButton.addEventListener('click', async e => {
|
||||||
|
exportToFile();
|
||||||
|
});
|
||||||
|
|
||||||
|
importButton.addEventListener('click', async e => {
|
||||||
|
importFileInput.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
importFileInput.addEventListener('change', async e => {
|
||||||
|
importFromFile();
|
||||||
|
});
|
||||||
|
|
||||||
async function cloneSchedule(includeAssignments) {
|
async function cloneSchedule(includeAssignments) {
|
||||||
let name = document.getElementById('cloneName').value;
|
let name = document.getElementById('cloneName').value;
|
||||||
if (name.length === 0) {
|
if (name.length === 0) {
|
||||||
|
@ -381,6 +465,11 @@ if (window.showDirectoryPicker) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Can't use real file system, so use OPFS instead.
|
||||||
|
await loadDir(await navigator.storage.getDirectory());
|
||||||
|
closeDirButton.addEventListener('click', e => closeDir());
|
||||||
|
}
|
||||||
|
|
||||||
function displayFullSchedule() {
|
function displayFullSchedule() {
|
||||||
(hash.day ? [hash.day] : schedule.all_days)
|
(hash.day ? [hash.day] : schedule.all_days)
|
||||||
|
@ -432,9 +521,6 @@ function displayIndividualSchedule(person) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const displaySettingsDiv = document.getElementById('displaySettings');
|
|
||||||
const displayDays = document.getElementById('displayDays');
|
|
||||||
const displayPeople = document.getElementById('displayPeople');
|
|
||||||
function updateDisplayOptions() {
|
function updateDisplayOptions() {
|
||||||
utils.clearChildren(displayDays);
|
utils.clearChildren(displayDays);
|
||||||
for (const day of [undefined, ...schedule.all_days]) {
|
for (const day of [undefined, ...schedule.all_days]) {
|
||||||
|
@ -490,8 +576,6 @@ async function refreshDisplay() {
|
||||||
displaySchedule();
|
displaySchedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
const warningsSection = document.getElementById('warningsSection');
|
|
||||||
const warningsDiv = document.getElementById('warnings');
|
|
||||||
function displayWarnings() {
|
function displayWarnings() {
|
||||||
utils.clearChildren(warningsDiv);
|
utils.clearChildren(warningsDiv);
|
||||||
|
|
||||||
|
@ -540,10 +624,6 @@ function displayWarnings() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const personInfoDiv = document.getElementById('personInfo');
|
|
||||||
const personStartTime = document.getElementById('person_start_time');
|
|
||||||
const personEndTime = document.getElementById('person_end_time');
|
|
||||||
const personDays = document.getElementById('person_days');
|
|
||||||
function displayPersonInfoDiv() {
|
function displayPersonInfoDiv() {
|
||||||
const singlePerson = hash.person && hash.person.name;
|
const singlePerson = hash.person && hash.person.name;
|
||||||
personInfoDiv.style.display = singlePerson ? '' : 'none';
|
personInfoDiv.style.display = singlePerson ? '' : 'none';
|
||||||
|
@ -813,8 +893,9 @@ document.getElementById('renameStaff').addEventListener('click', async e => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function updateToTeacherButtons() {
|
function updateToTeacherButtons() {
|
||||||
const isTeacher = schedule.all_teachers.includes(
|
const staffOptions = document.getElementById('removeStaff').selectedOptions;
|
||||||
document.getElementById('removeStaff').selectedOptions[0].value);
|
const isTeacher = staffOptions.length > 0 && schedule.all_teachers.includes(
|
||||||
|
staffOptions[0].value);
|
||||||
|
|
||||||
document.getElementById('toTeacher').style.display = isTeacher ? 'none' : '';
|
document.getElementById('toTeacher').style.display = isTeacher ? 'none' : '';
|
||||||
document.getElementById('toStaff').style.display = isTeacher ? '' : 'none';
|
document.getElementById('toStaff').style.display = isTeacher ? '' : 'none';
|
||||||
|
@ -843,13 +924,6 @@ document.getElementById('toStaff').addEventListener('click', async e => {
|
||||||
updateToTeacherButtons();
|
updateToTeacherButtons();
|
||||||
});
|
});
|
||||||
|
|
||||||
const assignmentFormDiv = document.getElementById('assignmentFormDiv');
|
|
||||||
const assignmentForm = document.getElementById('assignmentForm');
|
|
||||||
const assignmentSelector = assignmentForm.assignments;
|
|
||||||
const peopleTable = document.getElementById('peopleTable');
|
|
||||||
let peopleCheckboxes = undefined;
|
|
||||||
let selectedAssignment = undefined;
|
|
||||||
|
|
||||||
assignmentSelector.addEventListener('change', e => {
|
assignmentSelector.addEventListener('change', e => {
|
||||||
initializeAssignmentForm(e.target.selectedOptions[0].assignment);
|
initializeAssignmentForm(e.target.selectedOptions[0].assignment);
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="header" class="forms noprint">
|
<div id="header" class="forms noprint">
|
||||||
<p id="browserVersionWarning">
|
<p id="browserVersionWarning">
|
||||||
This website requires
|
Working with local directories requires
|
||||||
<a href="https://www.google.com/chrome/">Google Chrome 86+</a>
|
<a href="https://www.google.com/chrome/">Google Chrome 86+</a>
|
||||||
and does not work in Firefox due to using the
|
and does not work in Firefox due to using the
|
||||||
<a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API">File System Access API</a>
|
<a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API">File System Access API</a>
|
||||||
|
@ -25,6 +25,9 @@
|
||||||
<div id="scheduleSettings" class="forms noprint" style="display: none">
|
<div id="scheduleSettings" class="forms noprint" style="display: none">
|
||||||
<div id="selectScheduleDiv">
|
<div id="selectScheduleDiv">
|
||||||
<label>Schedule: <select id="schedules"></select></label>
|
<label>Schedule: <select id="schedules"></select></label>
|
||||||
|
<input type="file" id="importFile" accept="application/json" style="display:none" />
|
||||||
|
<button id="import">Import from file</button>
|
||||||
|
<button id="export">Export to file</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="clone">
|
<div id="clone">
|
||||||
<label>New schedule name: <input id="cloneName" pattern="[-_ a-zA-Z0-9]+"></label>
|
<label>New schedule name: <input id="cloneName" pattern="[-_ a-zA-Z0-9]+"></label>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user