MVP Raahaa & pudota lukujärjestys

This commit is contained in:
Juhani Krekelä 2024-05-26 16:17:50 +03:00
parent 707da4dcc2
commit 95ce125ec0
4 changed files with 148 additions and 3 deletions

View File

@ -69,6 +69,8 @@
<optgroup id="lukkari-valinta-tilat" label="Tilat">
</optgroup>
</select>
<table id="lukkari"></table>
<ul id="sijoittamattomat"></ul>
</details>
<script src="tietokanta.js"></script>

View File

@ -53,7 +53,7 @@ document.getElementById('tunnit-uusi').addEventListener('submit', (e) => {
const tilat = valitutHTMLLuokalla('tunnit-uusi-tila');
t.lisää(taulut.tunnit, {
nimi, luokat, opettajat, tilat,
milloin: new Array(kertaa),
milloin: new Array(kertaa).fill(null),
});
document.getElementById('tunnit-uusi-nimi').value = '';
document.getElementById('tunnit-uusi-kertaa').value = 1;
@ -63,6 +63,43 @@ document.getElementById('tunnit-uusi').addEventListener('submit', (e) => {
}));
});
document.getElementById('lukkari-valinta').addEventListener('input', () => {
päivitäLukkari();
});
let raahattava;
document.addEventListener('dragstart', (e) => {
raahattava = e.target;
});
function teePudotuskohteeksi(elementti) {
elementti.addEventListener('dragover', (e) => {
e.preventDefault();
});
elementti.addEventListener('drop', (e) => {
e.preventDefault();
const raahattavaId = ilmanPrefiksiä('lukkari-tunti-', raahattava.id);
const [tunti, toteutus] = raahattavaId.split('-').map((x) => Number.parseInt(x));
// XXX: Transaktio ja suoritus
if (elementti.id !== 'sijoittamattomat') {
const kohdeId = ilmanPrefiksiä('lukkari-solu-', elementti.id);
const ajoitus = kohdeId.split('-').map((x) => Number.parseInt(x));
_tietokanta.hae(taulut.tunnit, tunti).milloin[toteutus] = ajoitus;
} else {
_tietokanta.hae(taulut.tunnit, tunti).milloin[toteutus] = null;
}
päivitäLukkari();
});
}
function ilmanPrefiksiä(prefiksi, teksti) {
if (!teksti.startsWith(prefiksi)) {
throw new Error(`"${teksti}" ei ala prefiksillä "${prefiksi}"`);
}
return teksti.slice(prefiksi.length);
}
function valitutHTMLLuokalla(htmlLuokka) {
const valitut = [];
for (const valinta of document.getElementsByClassName(htmlLuokka)) {
@ -78,6 +115,7 @@ function suorita([tietokanta, muutokset]) {
suoritaMuutos(tietokanta, muutos);
}
tallennaTietokanta(tietokanta);
päivitäLukkari();
}
function suoritaMuutos(tietokanta, muutos) {
@ -147,11 +185,11 @@ function suoritaMuutos(tietokanta, muutos) {
} else if (taulu === taulut.tunnit && vanha === undefined) {
// Uusi tunti
const seuraavaId = idJälkeen(tietokanta, taulu, id,
(a, b) => vertaa(a.nimi, b.nimi)
(a, b) => vertaa(tuntiTeksti(tietokanta, a), tuntiTeksti(tietokanta, b))
);
const tunnitLista = document.getElementById('tunnit-lista');
// ks. kommentti uuden luokan tapauksessa
const seuraava = document.getElementById(`tunti-${id}`);
const seuraava = document.getElementById(`tunti-${seuraavaId}`);
tunnitLista.insertBefore(luoTunti(tietokanta, id, uusi), seuraava);
} else if (taulu === taulut.tunnit && uusi === undefined) {
poistaElementti(document.getElementById(`tunti-${id}`));
@ -335,3 +373,83 @@ function luoTilaVaihtoehto(id, nimi) {
option.appendChild(document.createTextNode(nimi));
return option;
}
let päivät = ['ma', 'ti', 'ke', 'to', 'pe'];
let ajat = ['8', '9', '10', '11', '12', '13', '14', '15'];
function päivitäLukkari() {
const taulukko = document.createElement('table');
taulukko.id = 'lukkari';
const taulukonOtsikko = document.createElement('caption');
taulukko.appendChild(taulukonOtsikko);
const rivit = document.createElement('tbody');
const otsikkoRivi = document.createElement('tr');
otsikkoRivi.appendChild(document.createElement('td'));
for (const päivä of päivät) {
const otsikko = document.createElement('th');
otsikko.appendChild(document.createTextNode(päivä));
otsikkoRivi.appendChild(otsikko);
}
rivit.appendChild(otsikkoRivi);
for (const [aikaId, aika] of numeroi(ajat)) {
const rivi = document.createElement('tr');
const otsikko = document.createElement('th');
otsikko.appendChild(document.createTextNode(aika));
rivi.appendChild(otsikko);
for (const [päiväId, päivä] of numeroi(päivät)) {
const solu = document.createElement('td');
solu.id = `lukkari-solu-${päiväId}-${aikaId}`;
teePudotuskohteeksi(solu);
const lista = document.createElement('ul');
solu.appendChild(lista);
rivi.appendChild(solu)
}
rivit.appendChild(rivi);
}
taulukko.appendChild(rivit);
const lista = document.createElement('ul');
lista.id = 'sijoittamattomat';
teePudotuskohteeksi(lista);
const valinta = document.getElementById('lukkari-valinta').value;
if (valinta !== '') {
let [tyyppi, valintaId] = valinta.split('-');
valintaId = Number.parseInt(valintaId);
const tunnit = _tietokanta.järjestyksessä(taulut.tunnit,
(a, b) => vertaa(tuntiTeksti(_tietokanta, a), tuntiTeksti(_tietokanta, b))
);
for (const id of tunnit) {
const tunti = _tietokanta.hae(taulut.tunnit, id);
if (
(tyyppi === 'luokka' && !tunti.luokat.includes(valintaId)) ||
(tyyppi === 'opettaja' && !tunti.opettajat.includes(valintaId)) ||
(tyyppi === 'tila' && !tunti.tilat.includes(valintaId))
) {
continue;
}
for (const [numero, toteutus] of numeroi(tunti.milloin)) {
const laatta = document.createElement('li');
laatta.id = `lukkari-tunti-${id}-${numero}`;
laatta.draggable = true;
laatta.appendChild(document.createTextNode(tuntiTeksti(_tietokanta, tunti)));
if (toteutus === null) {
lista.appendChild(laatta);
} else {
const [päiväId, aikaId] = toteutus;
const solu = rivit.children[aikaId + 1].children[päiväId + 1];
solu.firstChild.appendChild(laatta);
}
}
}
}
const vanhaTaulukko = document.getElementById('lukkari');
vanhaTaulukko.parentElement.replaceChild(taulukko, vanhaTaulukko);
const vanhaLista = document.getElementById('sijoittamattomat');
vanhaLista.parentElement.replaceChild(lista, vanhaLista);
}
function numeroi(iteroitava) {
return iteroitava.map((elementti, numero) => [numero, elementti]);
}

View File

@ -234,6 +234,19 @@ class Tietokanta {
return taulukko.map(([id, _]) => id);
}
suodata(taulu, suodatin) {
if (!this.taulut.has(taulu)) {
throw new Error(`ei taulua ${taulu}`);
}
const suodatetut = [];
for (const [id, sisältö] of this.taulut.get(taulu)) {
if (suodatin(sisältö)) {
suodatetut.push(id);
}
}
return suodatetut;
}
serialisoi() {
return JSON.stringify(this, (avain, arvo) => {
if (avain === 'historia') {

View File

@ -8,3 +8,15 @@
.valintalista > li {
flex: 1 fit-content;
}
#lukkari {
border-collapse: collapse;
}
#lukkari td {
border: 1px solid black;
}
#lukkari th {
border: 1px solid black;
}