lukujarjestaja/käyttöliittymä.js

284 lines
10 KiB
JavaScript
Raw Normal View History

2023-08-02 17:12:15 +00:00
'use strict';
document.getElementById('kumoa').addEventListener('click', () => {
suorita(_tietokanta.kumoa());
});
document.getElementById('luokat-uusi').addEventListener('submit', (e) => {
e.preventDefault();
suorita(_tietokanta.transaktio((t) => {
const luokanNimi = document.getElementById('luokat-uusi-nimi').value;
t.lisää(taulut.luokat, luokanNimi)
document.getElementById('luokat-uusi-nimi').value = '';
}));
});
2024-05-21 10:55:23 +00:00
document.getElementById('opettajat-uusi').addEventListener('submit', (e) => {
e.preventDefault();
suorita(_tietokanta.transaktio((t) => {
const nimi = document.getElementById('opettajat-uusi-nimi').value;
const lyhenne = document.getElementById('opettajat-uusi-lyhenne').value;
t.lisää(taulut.opettajat, {nimi, lyhenne});
document.getElementById('opettajat-uusi-nimi').value = '';
document.getElementById('opettajat-uusi-lyhenne').value = '';
2024-05-21 10:55:23 +00:00
}));
});
document.getElementById('opettajat-uusi-nimi').addEventListener('change', () => {
const nimi = document.getElementById('opettajat-uusi-nimi').value;
// TODO: Kunnollinen tuki grafeemiklustereille
// TODO: Älä ehdota lyhennettä, joka on jo käytössä
const lyhenne = nimi.split(' ')
.map((x) => String.fromCodePoint(x.codePointAt(0))).join('');
document.getElementById('opettajat-uusi-lyhenne').value = lyhenne;
});
2024-05-21 11:07:38 +00:00
document.getElementById('tilat-uusi').addEventListener('submit', (e) => {
e.preventDefault();
suorita(_tietokanta.transaktio((t) => {
const tilanNimi = document.getElementById('tilat-uusi-nimi').value;
t.lisää(taulut.tilat, tilanNimi)
document.getElementById('tilat-uusi-nimi').value = '';
}));
});
2024-05-22 11:17:26 +00:00
document.getElementById('tunnit-uusi').addEventListener('submit', (e) => {
e.preventDefault();
suorita(_tietokanta.transaktio((t) => {
const nimi = document.getElementById('tunnit-uusi-nimi').value;
const kertaa =
Number.parseInt(document.getElementById('tunnit-uusi-kertaa').value);
const luokat = valitutHTMLLuokalla('tunnit-uusi-luokka');
const opettajat = valitutHTMLLuokalla('tunnit-uusi-opettaja');
const tilat = valitutHTMLLuokalla('tunnit-uusi-tila');
t.lisää(taulut.tunnit, {
nimi, luokat, opettajat, tilat,
milloin: new Array(kertaa),
});
document.getElementById('tunnit-uusi-nimi').value = '';
document.getElementById('tunnit-uusi-kertaa').value = 1;
for (const valinta of document.getElementsByClassName('tunnit-uusi-valinta')) {
valinta.checked = false;
}
}));
});
function valitutHTMLLuokalla(htmlLuokka) {
const valitut = [];
for (const valinta of document.getElementsByClassName(htmlLuokka)) {
if (valinta.checked) {
valitut.push(Number.parseInt(valinta.value));
}
}
return valitut;
}
2024-05-17 12:32:19 +00:00
function suorita([tietokanta, muutokset]) {
for (const muutos of muutokset) {
2024-05-17 12:32:19 +00:00
suoritaMuutos(tietokanta, muutos);
2023-08-02 17:12:15 +00:00
}
tallennaTietokanta(tietokanta);
2023-08-02 17:12:15 +00:00
}
2024-05-17 12:32:19 +00:00
function suoritaMuutos(tietokanta, muutos) {
const {taulu, id, vanha, uusi} = muutos;
if (taulu === taulut.luokat && vanha === undefined) {
// Uusi luokka
2024-05-21 10:55:23 +00:00
const seuraavaId = idJälkeen(tietokanta, taulu, id, vertaa);
const luokatLista = document.getElementById('luokat-lista');
2024-05-17 12:32:19 +00:00
// getElementById palauttaa null:n, jos id:tä ei löydy. Jos tämä luokka
// on viimeinen, seuraavaId on undefined, eikä DOM:ssa ole luokkaa
// "luokka-undefined". seuraava on siis null silloin kuin tämä luokka
// tulee lisätä listan loppuun, joka vastaa insertBefore:n toimintaa
2024-05-22 11:17:26 +00:00
let seuraava = document.getElementById(`luokka-${seuraavaId}`);
luokatLista.insertBefore(luoLuokka(tietokanta, id, uusi), seuraava);
2024-05-22 11:17:26 +00:00
const tunnitUusiLuokat = document.getElementById('tunnit-uusi-luokat');
seuraava = document.getElementById(`tunnit-uusi-luokka-${seuraavaId}`);
tunnitUusiLuokat.insertBefore(luoLuokkaValinta(id, uusi), seuraava);
} else if (taulu === taulut.luokat && uusi === undefined) {
// Luokka poistettu
2024-05-21 11:25:30 +00:00
poistaElementti(document.getElementById(`luokka-${id}`));
2024-05-22 11:17:26 +00:00
poistaElementti(document.getElementById(`tunnit-uusi-luokka-${id}`));
2024-05-21 10:55:23 +00:00
// TODO: luokka muutos
} else if (taulu === taulut.opettajat && vanha === undefined) {
// Uusi opettaja
const seuraavaId = idJälkeen(tietokanta, taulu, id,
(a, b) => vertaa(a.nimi, b.nimi)
);
const opettajatLista = document.getElementById('opettajat-lista');
// ks. kommentti uuden luokan tapauksessa
2024-05-22 11:17:26 +00:00
let seuraava = document.getElementById(`opettaja-${seuraavaId}`);
2024-05-21 10:55:23 +00:00
opettajatLista.insertBefore(luoOpettaja(id, uusi), seuraava);
2024-05-22 11:17:26 +00:00
const tunnitUusiOpettajat = document.getElementById('tunnit-uusi-opettajat');
seuraava = document.getElementById(`tunnit-uusi-opettaja-${seuraavaId}`);
tunnitUusiOpettajat.insertBefore(luoOpettajaValinta(id, uusi), seuraava);
2024-05-21 10:55:23 +00:00
} else if (taulu === taulut.opettajat && uusi === undefined) {
// Opettaja poistettu
2024-05-21 11:25:30 +00:00
poistaElementti(document.getElementById(`opettaja-${id}`));
2024-05-22 11:17:26 +00:00
poistaElementti(document.getElementById(`tunnit-uusi-opettaja-${id}`));
2024-05-21 10:55:23 +00:00
// TODO: opettaja muutos
2024-05-21 11:07:38 +00:00
} else if (taulu === taulut.tilat && vanha === undefined) {
// Uusi tila
const seuraavaId = idJälkeen(tietokanta, taulu, id, vertaa);
const tilatLista = document.getElementById('tilat-lista');
2024-05-22 11:17:26 +00:00
let seuraava = document.getElementById(`tila-${seuraavaId}`);
2024-05-21 11:07:38 +00:00
tilatLista.insertBefore(luoTila(id, uusi), seuraava);
2024-05-22 11:17:26 +00:00
const tunnitUusiTilat = document.getElementById(`tunnit-uusi-tilat`);
seuraava = document.getElementById(`tunnit-uusi-tila-${seuraavaId}`);
tunnitUusiTilat.insertBefore(luoTilaValinta(id, uusi), seuraava);
2024-05-21 11:07:38 +00:00
} else if (taulu === taulut.tilat && uusi === undefined) {
// Tila poistettu
2024-05-21 11:25:30 +00:00
poistaElementti(document.getElementById(`tila-${id}`));
2024-05-22 11:17:26 +00:00
poistaElementti(document.getElementById(`tunnit-uusi-tila-${id}`));
2024-05-21 11:07:38 +00:00
// TODO: tila muutos
2024-05-22 11:17:26 +00:00
} else if (taulu === taulut.tunnit && vanha === undefined) {
// Uusi tunti
2024-05-24 11:04:17 +00:00
const seuraavaId = idJälkeen(tietokanta, taulu, id,
(a, b) => vertaa(a.nimi, b.nimi)
);
2024-05-22 11:17:26 +00:00
const tunnitLista = document.getElementById('tunnit-lista');
2024-05-24 11:04:17 +00:00
const seuraava = document.getElementById(`tunti-${id}`);
tunnitLista.insertBefore(luoTunti(tietokanta, id, uusi), seuraava);
2024-05-23 11:53:01 +00:00
} else if (taulu === taulut.tunnit && uusi === undefined) {
poistaElementti(document.getElementById(`tunti-${id}`));
// TODO: tunti muutos
} else {
throw new Error(`Ei toteutettu ${taulu} ${id} ${vanha} ${uusi}`);
}
}
2024-05-21 10:55:23 +00:00
function idJälkeen(tietokanta, taulu, id, vertaa) {
const järjestys = tietokanta.järjestyksessä(taulu, vertaa);
return järjestys[järjestys.indexOf(id) + 1];
}
2024-05-17 12:32:19 +00:00
function vertaa(a, b) {
// TODO: Parempi vertailufunktio?
return a.localeCompare(b);
}
2024-05-21 11:25:30 +00:00
function poistaElementti(elementti) {
elementti.parentElement.removeChild(elementti);
}
function luoLuokka(tietokanta, id, nimi) {
const li = document.createElement('li');
li.id = `luokka-${id}`;
const poistoPainike = document.createElement('input');
poistoPainike.type = 'button';
poistoPainike.value = '-';
poistoPainike.addEventListener('click', () => {
suorita(_tietokanta.transaktio((t) => {
const käyttävät =
t.suodata(taulut.tunnit, (tunti) => tunti.luokat.includes(id))
.map((x) => tuntiTeksti(tietokanta, t.hae(taulut.tunnit, x)));
if (käyttävät.length === 0) {
t.poista(taulut.luokat, id);
} else {
const lista = käyttävät.join('\n- ');
alert(`Ei voida poistaa ennen tunteja:\n- ${lista}`);
}
}));
});
li.appendChild(poistoPainike);
li.appendChild(document.createTextNode(nimi));
return li;
2023-08-02 17:12:15 +00:00
}
2024-05-21 10:55:23 +00:00
function luoOpettaja(id, {nimi, lyhenne}) {
const li = document.createElement('li');
li.id = `opettaja-${id}`;
const poistoPainike = document.createElement('input');
poistoPainike.type = 'button';
poistoPainike.value = '-';
poistoPainike.addEventListener('click', () => {
suorita(_tietokanta.transaktio((t) => {
t.poista(taulut.opettajat, id);
}));
});
li.appendChild(poistoPainike);
li.appendChild(document.createTextNode(`${nimi} (${lyhenne})`));
return li;
}
2024-05-21 11:07:38 +00:00
function luoTila(id, nimi) {
const li = document.createElement('li');
li.id = `tila-${id}`;
const poistoPainike = document.createElement('input');
poistoPainike.type = 'button';
poistoPainike.value = '-';
poistoPainike.addEventListener('click', () => {
suorita(_tietokanta.transaktio((t) => {
t.poista(taulut.tilat, id);
}));
});
li.appendChild(poistoPainike);
li.appendChild(document.createTextNode(nimi));
return li;
}
2024-05-22 11:17:26 +00:00
function luoTunti(tietokanta, id, tunti) {
const li = document.createElement('li');
li.id = `tunti-${id}`;
const poistoPainike = document.createElement('input');
poistoPainike.type = 'button';
poistoPainike.value = '-';
poistoPainike.addEventListener('click', () => {
suorita(_tietokanta.transaktio((t) => {
t.poista(taulut.tunnit, id);
}));
});
li.appendChild(poistoPainike);
li.appendChild(document.createTextNode(tuntiTeksti(tietokanta, tunti)));
return li;
}
function tuntiTeksti(tietokanta, tunti) {
const kertaa = tunti.milloin.length;
const nimi = tunti.nimi;
const luokat = tunti.luokat.map((x) => tietokanta.hae(taulut.luokat, x));
const opettajat = tunti.opettajat
.map((x) => tietokanta.hae(taulut.opettajat, x).lyhenne);
const tilat = tunti.tilat.map((x) => tietokanta.hae(taulut.tilat, x));
2024-05-24 11:04:17 +00:00
return `${luokat} ${opettajat} ${nimi}×${kertaa} tilassa ${tilat}`;
2024-05-22 11:17:26 +00:00
}
function luoLuokkaValinta(id, nimi) {
const li = document.createElement('li');
li.id = `tunnit-uusi-luokka-${id}`;
const valinta = document.createElement('input');
valinta.type = 'checkbox';
valinta.classList.add('tunnit-uusi-valinta');
valinta.classList.add('tunnit-uusi-luokka');
valinta.value = id;
li.appendChild(valinta);
li.appendChild(document.createTextNode(nimi));
return li;
}
function luoOpettajaValinta(id, {nimi, lyhenne}) {
const li = document.createElement('li');
li.id = `tunnit-uusi-opettaja-${id}`;
const valinta = document.createElement('input');
valinta.type = 'checkbox';
valinta.classList.add('tunnit-uusi-valinta');
valinta.classList.add('tunnit-uusi-opettaja');
valinta.value = id;
li.appendChild(valinta);
li.appendChild(document.createTextNode(`${nimi} (${lyhenne})`));
return li;
}
function luoTilaValinta(id, nimi) {
const li = document.createElement('li');
li.id = `tunnit-uusi-tila-${id}`;
const valinta = document.createElement('input');
valinta.type = 'checkbox';
valinta.classList.add('tunnit-uusi-valinta');
valinta.classList.add('tunnit-uusi-tila');
valinta.value = id;
li.appendChild(valinta);
li.appendChild(document.createTextNode(nimi));
return li;
}