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 reopenDirButton = document.getElementById('reopenDir');
|
||||
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 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 backupsDir = null;
|
||||
let fileHandle = null;
|
||||
|
@ -145,6 +171,64 @@ document.getElementById('restoreBackup').addEventListener('click', async e => {
|
|||
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) {
|
||||
let name = document.getElementById('cloneName').value;
|
||||
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() {
|
||||
(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() {
|
||||
utils.clearChildren(displayDays);
|
||||
for (const day of [undefined, ...schedule.all_days]) {
|
||||
|
@ -490,8 +576,6 @@ async function refreshDisplay() {
|
|||
displaySchedule();
|
||||
}
|
||||
|
||||
const warningsSection = document.getElementById('warningsSection');
|
||||
const warningsDiv = document.getElementById('warnings');
|
||||
function displayWarnings() {
|
||||
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() {
|
||||
const singlePerson = hash.person && hash.person.name;
|
||||
personInfoDiv.style.display = singlePerson ? '' : 'none';
|
||||
|
@ -813,8 +893,9 @@ document.getElementById('renameStaff').addEventListener('click', async e => {
|
|||
});
|
||||
|
||||
function updateToTeacherButtons() {
|
||||
const isTeacher = schedule.all_teachers.includes(
|
||||
document.getElementById('removeStaff').selectedOptions[0].value);
|
||||
const staffOptions = document.getElementById('removeStaff').selectedOptions;
|
||||
const isTeacher = staffOptions.length > 0 && schedule.all_teachers.includes(
|
||||
staffOptions[0].value);
|
||||
|
||||
document.getElementById('toTeacher').style.display = isTeacher ? 'none' : '';
|
||||
document.getElementById('toStaff').style.display = isTeacher ? '' : 'none';
|
||||
|
@ -843,13 +924,6 @@ document.getElementById('toStaff').addEventListener('click', async e => {
|
|||
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 => {
|
||||
initializeAssignmentForm(e.target.selectedOptions[0].assignment);
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<body>
|
||||
<div id="header" class="forms noprint">
|
||||
<p id="browserVersionWarning">
|
||||
This website requires
|
||||
Working with local directories requires
|
||||
<a href="https://www.google.com/chrome/">Google Chrome 86+</a>
|
||||
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>
|
||||
|
@ -25,6 +25,9 @@
|
|||
<div id="scheduleSettings" class="forms noprint" style="display: none">
|
||||
<div id="selectScheduleDiv">
|
||||
<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 id="clone">
|
||||
<label>New schedule name: <input id="cloneName" pattern="[-_ a-zA-Z0-9]+"></label>
|
||||
|
|
Loading…
Reference in New Issue
Block a user