diff --git a/index.html b/index.html index 385d7a4..4b041bc 100644 --- a/index.html +++ b/index.html @@ -43,6 +43,9 @@ #opettajat > li > span { margin-left: 0.5em; } + #tilat > li > span { + margin-left: 0.5em; + } #tunti-kertaa-viikossa { width: 3em; } @@ -78,6 +81,18 @@ +
+ Tilat +
+
+ + + +
+ +
+
+
Tunnit
@@ -88,6 +103,8 @@ + + diff --git a/käyttöliittymä.js b/käyttöliittymä.js index 3638925..760ce76 100644 --- a/käyttöliittymä.js +++ b/käyttöliittymä.js @@ -46,6 +46,14 @@ document.getElementById('lisää-opettaja').addEventListener('submit', (tapahtum } }); +document.getElementById('lisää-tila').addEventListener('submit', (tapahtuma) => { + tapahtuma.preventDefault(); + let nimiElementti = document.getElementById('tila-nimi'); + suorita(tapahtumaTyypit.lisääTila, nimiElementti.value); + nimiElementti.value = ''; + piirräKaikki(); +}); + document.getElementById('opettaja-nimi').addEventListener('input', () => { let osat = document.getElementById('opettaja-nimi').value.split(' '); let lyhenne = []; @@ -66,17 +74,27 @@ document.getElementById('lisää-tunti').addEventListener('submit', (tapahtuma) let nimiElementti = document.getElementById('tunti-nimi'); let luokkaElementti = document.getElementById('tunti-luokka'); let opettajaElementti = document.getElementById('tunti-opettaja'); + let tilaElementti = document.getElementById('tunti-tila'); let kertaaViikossaElementti = document.getElementById('tunti-kertaa-viikossa'); let nimi = nimiElementti.value; let luokka = luokkaElementti.value; let opettajaLyhenne = opettajaElementti.value; + let tila = parseInt(tilaElementti.value); let kertaaViikossa = parseInt(kertaaViikossaElementti.value); - suorita(tapahtumaTyypit.lisääTunti, nimi, luokka, opettajaLyhenne, kertaaViikossa); + suorita( + tapahtumaTyypit.lisääTunti, + nimi, + luokka, + opettajaLyhenne, + tila, + kertaaViikossa + ); nimiElementti.value = ''; luokkaElementti.value = ''; opettajaElementti.value = ''; + tilaElementti.value = ''; kertaaViikossaElementti.value = 1; piirräKaikki(); @@ -85,6 +103,7 @@ document.getElementById('lisää-tunti').addEventListener('submit', (tapahtuma) function piirräKaikki() { piirräLuokat(); piirräOpettajat(); + piirräTilat(); piirräTunnit(); } @@ -252,6 +271,52 @@ function luoOpettajaListassa(lyhenne, nimi) { return opettajaListassa; } +function piirräTilat() { + let vanhaTilaLista = document.getElementById('tilat'); + let tilaLista = luoTilaLista(); + vanhaTilaLista.parentNode.replaceChild( + tilaLista, + vanhaTilaLista + ); + + let vanhaTuntiTilaValinta = document.getElementById('tunti-tila'); + let tuntiTilaValinta = document.createElement('select'); + tuntiTilaValinta.id = 'tunti-tila'; + tuntiTilaValinta.required = true; + for (let [id, tila] of tilat.tilat()) { + let valinta = document.createElement('option'); + valinta.appendChild(document.createTextNode(tila)); + valinta.value = id; + tuntiTilaValinta.appendChild(valinta); + } + tuntiTilaValinta.value = ''; + vanhaTuntiTilaValinta.parentNode.replaceChild( + tuntiTilaValinta, + vanhaTuntiTilaValinta + ); +} + +function luoTilaLista() { + let tilaLista = document.createElement('ul'); + tilaLista.id = 'tilat'; + + for (let [id, tila] of tilat.tilat()) { + let tilaListassa = document.createElement('li'); + tilaListassa.appendChild(luoPainike('-', () => { + suorita(tapahtumaTyypit.poistaTila, id); + piirräKaikki(); + })); + + let tilanNimi = document.createElement('span'); + tilanNimi.appendChild(document.createTextNode(`${tila}`)); + tilaListassa.appendChild(tilanNimi); + + tilaLista.appendChild(tilaListassa); + } + + return tilaLista; +} + function piirräTunnit() { let vanhaTuntiLista = document.getElementById('tunnit'); let tuntiLista = luoTuntiLista(); @@ -270,12 +335,13 @@ function luoTuntiLista() { let nimi = tunti.nimi; let luokat = tunti.luokat.alkiot().join(', '); let opettajat = tunti.opettajaLyhenteet.alkiot().join(', '); + let tunninTilat = tilojenNimet(tilat, tunti.tilat.alkiot()); let kertaaViikossa = tunti.kertaaViikossa; let teksti; if (kertaaViikossa === 1) { - teksti = `${nimi} ${luokat} ${opettajat}`; + teksti = `${nimi} ${luokat} ${opettajat} ${tunninTilat}`; } else { - teksti = `${nimi} ${luokat} ${opettajat} ×${kertaaViikossa}`; + teksti = `${nimi} ${luokat} ${opettajat} ${tunninTilat} ×${kertaaViikossa}`; } tuntiListassa.appendChild(document.createTextNode(teksti)); tuntiLista.appendChild(tuntiListassa); diff --git a/tietomalli.js b/tietomalli.js index 1d972e8..96d2c37 100644 --- a/tietomalli.js +++ b/tietomalli.js @@ -10,6 +10,9 @@ const tapahtumaTyypit = { lisääOpettaja: 'lisääOpettaja', poistaOpettaja: 'poistaOpettaja', + lisääTila: 'lisääTila', + poistaTila: 'poistaTila', + lisääTunti: 'lisääTunti', poistaTunti: 'poistaTunti', }; @@ -22,7 +25,7 @@ class Tapahtuma { } let historia, tulevaisuus; -let luokkaAsteet, opettajat, tunnit; +let luokkaAsteet, opettajat, tilat, tunnit; alustaMalli(); function alustaMalli() { @@ -30,6 +33,7 @@ function alustaMalli() { tulevaisuus = []; luokkaAsteet = new LuokkaAsteet(); opettajat = new Opettajat(); + tilat = new Tilat(); tunnit = new Tunnit(); } @@ -103,8 +107,21 @@ function suorita(tyyppi, ...argumentit) { } break; + case tapahtumaTyypit.lisääTila: + assertEq('lisääTila argumentit määrä', argumentit.length, 1); + paluuarvo = tilat.lisää(...argumentit); + break; + case tapahtumaTyypit.poistaTila: + assertEq('poistaTila argumentit määrä', argumentit.length, 1); + let [poistettuTila] = argumentit; + tilat.poista(poistettuTila); + for (let [_, tunti] of tunnit.tunnit) { + tunti.tilat.poista(poistettuTila); + } + break; + case tapahtumaTyypit.lisääTunti: - assertEq('lisääTunti argumentit määrä', argumentit.length, 4); + assertEq('lisääTunti argumentit määrä', argumentit.length, 5); paluuarvo = tunnit.lisää(...argumentit); break; case tapahtumaTyypit.poistaTunti: @@ -154,12 +171,14 @@ testi('mallin alustaminen', () => { tulevaisuus = undefined; luokkaAsteet = undefined; opettajat = undefined; + tilat = undefined; tunnit = undefined; alustaMalli(); assertNe('historia', historia, undefined); assertNe('tulevaisuus', tulevaisuus, undefined); assertNe('luokkaAsteet', luokkaAsteet, undefined); assertNe('opettajat', opettajat, undefined); + assertNe('tilat', tilat, undefined); assertNe('tunnit', tunnit, undefined); }); @@ -262,6 +281,16 @@ testi('opettajien käsittely', () => { assertEq('poistettua', opettajat.opettajat(), []); }); +testi('tilojen käsittely', () => { + alustaMalli(); + assertEq('aluksi', tilat.tilat(), []); + assertEq('1A', suorita(tapahtumaTyypit.lisääTila, '1A'), 0); + assertEq('lisättyä', tilat.tilat(), [[0, '1A']]); + suorita(tapahtumaTyypit.poistaTila, 0); + assertEq('poistettua', tilat.tilat(), []); + alustaMalli(); +}); + testi('tuntien käsittely', () => { alustaMalli(); suorita(tapahtumaTyypit.lisääAste); @@ -270,18 +299,21 @@ testi('tuntien käsittely', () => { suorita(tapahtumaTyypit.lisääOpettaja, 'KV', 'Kari Virtanen'); suorita(tapahtumaTyypit.lisääOpettaja, 'AS', 'Aili Savolainen'); suorita(tapahtumaTyypit.lisääOpettaja, 'MM', 'Maija Meikäläinen'); + suorita(tapahtumaTyypit.lisääTila, '1A'); + suorita(tapahtumaTyypit.lisääTila, '5B'); + suorita(tapahtumaTyypit.lisääTila, 'Käsityöluokka'); assertEq('aluksi', tunnit.järjestyksessä(), []); assertEq('historia', - suorita(tapahtumaTyypit.lisääTunti, 'Historia', '5B', 'KV', 1), + suorita(tapahtumaTyypit.lisääTunti, 'Historia', '5B', 'KV', 1, 1), 0 ); assertEq('äidinkieli', - suorita(tapahtumaTyypit.lisääTunti, 'Äidinkieli', '1A', 'AS', 3), + suorita(tapahtumaTyypit.lisääTunti, 'Äidinkieli', '1A', 'AS', 0, 3), 1 ); assertEq('kuvataide', - suorita(tapahtumaTyypit.lisääTunti, 'Kuvataide', '5A', 'MM', 1), + suorita(tapahtumaTyypit.lisääTunti, 'Kuvataide', '5A', 'MM', 2, 1), 2 ); assertEq('lisättyä pituus', tunnit.järjestyksessä().length, 3); @@ -306,6 +338,11 @@ testi('tuntien käsittely', () => { assertEq('opettaja poistettua 1', tunnit.järjestyksessä()[1][1].opettajaLyhenteet.alkiot(), ['MM']); assertEq('opettaja poistettua 2', tunnit.järjestyksessä()[2][1].opettajaLyhenteet.alkiot(), ['AS']); + suorita(tapahtumaTyypit.poistaTila, 1); + assertEq('tila poistettua 0', tunnit.järjestyksessä()[0][1].tilat.alkiot(), []); + assertEq('tila poistettua 1', tunnit.järjestyksessä()[1][1].tilat.alkiot(), [2]); + assertEq('tila poistettua 2', tunnit.järjestyksessä()[2][1].tilat.alkiot(), [0]); + suorita(tapahtumaTyypit.poistaTunti, 0); assertEq('poistettua pituus', tunnit.järjestyksessä().length, 2); diff --git a/tietotyypit.js b/tietotyypit.js index 33ac0a3..95f0fd7 100644 --- a/tietotyypit.js +++ b/tietotyypit.js @@ -109,11 +109,55 @@ class Opettajat { } } +class Tilat { + #tilat = new Map(); + #seuraavaId = 0; + + tilat() { + let tilat = []; + for (let [id, tila] of this.#tilat) { + tilat.push([id, tila]); + } + tilat.sort((a, b) => { + return vertaa(a[1], b[1]); + }); + return tilat; + } + + id(id) { + if (!this.#tilat.has(id)) { + throw new Error(`ei tilaa ID:llä ${id}`); + } + return this.#tilat.get(id); + } + + lisää(tila) { + let id = this.#seuraavaId++; + this.#tilat.set(id, tila); + return id; + } + + poista(id) { + if (!this.#tilat.delete(id)) { + throw new Error(`ei tilaa ID:llä ${id}`); + } + } +} + +function tilojenNimet(tilat, tilaIDt) { + let nimet = []; + for (let id of tilaIDt) { + nimet.push(tilat.id(id)); + } + return nimet; +} + class Tunti { - constructor(nimi, luokat, opettajaLyhenteet, kertaaViikossa) { + constructor(nimi, luokat, opettajaLyhenteet, tilat, kertaaViikossa) { this.nimi = nimi; this.luokat = new Joukko(luokat); this.opettajaLyhenteet = new Joukko(opettajaLyhenteet); + this.tilat = new Joukko(tilat); this.kertaaViikossa = kertaaViikossa; } } @@ -122,11 +166,11 @@ class Tunnit { tunnit = new Map(); #seuraavaId = 0; - lisää(nimi, luokka, opettajaLyhenne, kertaaViikossa) { + lisää(nimi, luokka, opettajaLyhenne, tila, kertaaViikossa) { let id = this.#seuraavaId++; this.tunnit.set( id, - new Tunti(nimi, [luokka], [opettajaLyhenne], kertaaViikossa) + new Tunti(nimi, [luokka], [opettajaLyhenne], [tila], kertaaViikossa) ); return id; } @@ -152,6 +196,8 @@ class Tunnit { if (tulos === 0) { tulos = vertaa(a[1].opettajaLyhenteet.alkiot(), b[1].opettajaLyhenteet.alkiot()); } + // TODO: Vertaa tilojen nimiä + // TODO: Korjaa niin, että osaa verrata okein listoja if (tulos === 0) { tulos = vertaa(a[1].kertaaViikossa, b[1].kertaaViikossa); } @@ -323,36 +369,66 @@ testi('opettajien lyhenteen', () => { assertEq('ZZ', opettajat.lyhenne('ZZ'), undefined); }); +testi('tilojen lisääminen', () => { + let tilat = new Tilat(); + assertEq('käsityöluokka', tilat.lisää('Käsityöluokka'), 0); + assertEq('1A', tilat.lisää('1A'), 1); + assertEq('lisättyä', tilat.tilat(), [[1, '1A'], [0, 'Käsityöluokka']]); +}); + +testi('tilojen poistaminen', () => { + let tilat = new Tilat(); + tilat.lisää('Käsityöluokka'); + tilat.lisää('1A'); + tilat.poista(0); + tilat.poista(1); + assertEq('poistettua', tilat.tilat(), []); + assertThrow('jo poistettu', 'ei tilaa ID:llä 1', () => { + tilat.poista(1); + }); + assertEq('Käsityöluokka uudestaan', tilat.lisää('Käsityöluokka'), 2); +}); + +testi('tilojen nimet', () => { + let tilat = new Tilat(); + tilat.lisää('Käsityöluokka'); + tilat.lisää('1A'); + tilat.lisää('5A'); + assertEq('', tilojenNimet(tilat, [1, 0, 2]), ['1A', 'Käsityöluokka', '5A']); +}); + testi('tuntien lisääminen', () => { let tunnit = new Tunnit(); - assertEq('historia', tunnit.lisää('Historia', '5B', 'KV', 1), 0); - assertEq('äidinkieli', tunnit.lisää('Äidinkieli', '1A', 'AS', 3), 1); + assertEq('historia', tunnit.lisää('Historia', '5B', 'KV', 0, 1), 0); + assertEq('äidinkieli', tunnit.lisää('Äidinkieli', '1A', 'AS', 1, 3), 1); assertEq('historia nimi', tunnit.tunnit.get(0).nimi, 'Historia'); assertEq('historia luokat', tunnit.tunnit.get(0).luokat.alkiot(), ['5B']); assertEq('historia opettajat', tunnit.tunnit.get(0).opettajaLyhenteet.alkiot(), ['KV']); + assertEq('historia tilat', tunnit.tunnit.get(0).tilat.alkiot(), [0]); assertEq('historia viikossa', tunnit.tunnit.get(0).kertaaViikossa, 1); assertEq('äidinkieli nimi', tunnit.tunnit.get(1).nimi, 'Äidinkieli'); assertEq('äidinkieli luokat', tunnit.tunnit.get(1).luokat.alkiot(), ['1A']); + assertEq('äidinkieli tilat', tunnit.tunnit.get(1).tilat.alkiot(), [1]); assertEq('äidinkieli opettajat', tunnit.tunnit.get(1).opettajaLyhenteet.alkiot(), ['AS']); assertEq('äidinkieli viikossa', tunnit.tunnit.get(1).kertaaViikossa, 3); }); testi('tuntien poistaminen', () => { let tunnit = new Tunnit(); - tunnit.lisää('Historia', '5B', 'KV', 1); - tunnit.lisää('Äidinkieli', '1B', 'AS', 3); + tunnit.lisää('Historia', '5B', 'KV', 0, 1); + tunnit.lisää('Äidinkieli', '1B', 'AS', 1, 3); tunnit.poista(0); tunnit.poista(1); assertThrow('jo poistettu', 'ei tuntia ID:llä 1', () => { tunnit.poista(1); }); - assertEq('kuvataide', tunnit.lisää('Kuvataide', '6A', 'MM', 1), 2); + assertEq('kuvataide', tunnit.lisää('Kuvataide', '6A', 'MM', 2, 1), 2); }); testi('tuntien järjestys', () => { let tunnit = new Tunnit(); - tunnit.lisää('Historia', '5B', 'KV', 1); - tunnit.lisää('Äidinkieli', '1B', 'AS', 3); + tunnit.lisää('Historia', '5B', 'KV', 0, 1); + tunnit.lisää('Äidinkieli', '1B', 'AS', 1, 3); assertEq('aluksi', tunnit.järjestyksessä()[0][1].nimi, 'Historia'); tunnit.tunnit.get(1).nimi = 'Historia'; assertEq('sama nimi', tunnit.järjestyksessä()[0][1].luokat.alkiot(), ['1B']);