Okomentování mého zběsilého frontendu ke korekturovátku
This commit is contained in:
parent
82dc7e1a83
commit
0722729bcd
9 changed files with 287 additions and 33 deletions
korektury/templates/korektury/korekturovatko
|
@ -1,3 +1,4 @@
|
||||||
|
{# Část korekturovátka, která obsahuje všechno okolo korektur #}
|
||||||
{% include "korektury/korekturovatko/moduly/schovani_korektur.html" %}
|
{% include "korektury/korekturovatko/moduly/schovani_korektur.html" %}
|
||||||
|
|
||||||
{% include "korektury/korekturovatko/moduly/edit_komentar.html" %}
|
{% include "korektury/korekturovatko/moduly/edit_komentar.html" %}
|
||||||
|
@ -12,10 +13,11 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/**
|
/**
|
||||||
*
|
* Fetchne korektury a komentáře a na základě toho aktualizuje všechno
|
||||||
* @param {RequestInit} data
|
* (korektury, komentáře, zásluhy, počty korektur v daných stavech, umístění korektur)
|
||||||
* @param {Boolean} catchError
|
* @param {RequestInit} data FormData a jiné náležitosti (method: POST) posílané při přidání/úpravě korektury/komentáře
|
||||||
* @param pri_uspechu Akce, která se má provést při úspěchu (speciálně zavřít formulář)
|
* @param {Boolean} catchError jestli padat hlasitě (pokud se aktualizuje automaticky a spadne to např. na nepřítomnost sítě, pak není třeba informovat uživatele)
|
||||||
|
* @param {(() => *)?} pri_uspechu akce, která se má provést při úspěchu (speciálně zavřít formulář)
|
||||||
*/
|
*/
|
||||||
function aktualizuj_vse(data={}, catchError=true, pri_uspechu=null) { // FIXME není mi jasné, zda v {} nemá být `cache: "no-store"`, aby prohlížeč necachoval GET.
|
function aktualizuj_vse(data={}, catchError=true, pri_uspechu=null) { // FIXME není mi jasné, zda v {} nemá být `cache: "no-store"`, aby prohlížeč necachoval GET.
|
||||||
fetch('{% url "korektury_api_opravy_a_komentare" korekturovanepdf.id %}', data)
|
fetch('{% url "korektury_api_opravy_a_komentare" korekturovanepdf.id %}', data)
|
||||||
|
@ -39,7 +41,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", _ => {
|
window.addEventListener("load", _ => {
|
||||||
aktualizuj_vse({}, true, _ => {
|
aktualizuj_vse({}, true, () => {
|
||||||
if (location.hash !== "") location.hash = location.hash; // Po rozházení korektur sescrollujeme na kotvu v URL
|
if (location.hash !== "") location.hash = location.hash; // Po rozházení korektur sescrollujeme na kotvu v URL
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -48,8 +50,13 @@
|
||||||
setInterval(() => aktualizuj_vse({}, false), 120000); // Každý dvě minuty fetchni korektury
|
setInterval(() => aktualizuj_vse({}, false), 120000); // Každý dvě minuty fetchni korektury
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{# Formulář, který mouhou použít tlačítka bez svého formuláře k vytvoření POST requestu, viz CSRF_FORM níže #}
|
||||||
<form id='CSRF_form' style='display: none'>{% csrf_token %}</form>
|
<form id='CSRF_form' style='display: none'>{% csrf_token %}</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* Formulář, který mouhou použít tlačítka bez svého formuláře k vytvoření POST requestu
|
||||||
|
* @type {HTMLFormElement}
|
||||||
|
*/
|
||||||
const CSRF_FORM = document.getElementById('CSRF_form');
|
const CSRF_FORM = document.getElementById('CSRF_form');
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{# Okolí samotného hlavni_cast_korekturovatka.html, tedy „povinné HTML věci“, informace o korekturovaném PDF a starání se o stav PDF #}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
<html lang='cs'>
|
<html lang='cs'>
|
||||||
|
@ -36,8 +37,13 @@
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* HTML prvek, kam se zapíší (pomocí .innerHTML) počty korektur jednotlivých autorů
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
const span_s_pocty_autoru = document.getElementById("pocty_autoru")
|
const span_s_pocty_autoru = document.getElementById("pocty_autoru")
|
||||||
|
|
||||||
|
/** Aktualizuje, kolik který autor má komentářů u daného korekturovaného PDF. */
|
||||||
function aktualizuj_pocty_zasluh() {
|
function aktualizuj_pocty_zasluh() {
|
||||||
const pocty_autoru = {};
|
const pocty_autoru = {};
|
||||||
for (let komentar of Object.values(komentare)) {
|
for (let komentar of Object.values(komentare)) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{# Template starající se o tlačítka v levém dolním rohu, především skákající na další/předchozí korekturu. #}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
<div id="korektury-sipky">
|
<div id="korektury-sipky">
|
||||||
|
@ -29,7 +30,6 @@ Nemusíš mačkat, pokud ti stačí, že se korektury aktualizují samy každé
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Přidání event listenerů
|
|
||||||
document.getElementById('predchozi-korektura').addEventListener('click', _ => { dalsi_nebo_predchozi_korektura(false) });
|
document.getElementById('predchozi-korektura').addEventListener('click', _ => { dalsi_nebo_predchozi_korektura(false) });
|
||||||
document.getElementById('dalsi-korektura').addEventListener('click', _ => { dalsi_nebo_predchozi_korektura(true) });
|
document.getElementById('dalsi-korektura').addEventListener('click', _ => { dalsi_nebo_predchozi_korektura(true) });
|
||||||
document.getElementById('predchozi-korektura-k-oprave').addEventListener('click', _ => { dalsi_nebo_predchozi_korektura(false, "k_oprave") });
|
document.getElementById('predchozi-korektura-k-oprave').addEventListener('click', _ => { dalsi_nebo_predchozi_korektura(false, "k_oprave") });
|
||||||
|
@ -40,6 +40,12 @@ Nemusíš mačkat, pokud ti stačí, že se korektury aktualizují samy každé
|
||||||
// FIXME není mi jasné, zda v {} nemá být `cache: "no-store"`, aby prohlížeč necachoval GET.
|
// FIXME není mi jasné, zda v {} nemá být `cache: "no-store"`, aby prohlížeč necachoval GET.
|
||||||
document.getElementById("korektury-aktualizace").addEventListener("click", _ => aktualizuj_vse({}, false));
|
document.getElementById("korektury-aktualizace").addEventListener("click", _ => aktualizuj_vse({}, false));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sescrolluje na další nebo předchozí (vůči hornímu okraji okna) korekturu (v daném stavu).
|
||||||
|
* V případě neexistence takové korektury vyhodí alert.
|
||||||
|
* @param {boolean} dalsi reprezentuje, zda chceme další nebo předchozí korekturu
|
||||||
|
* @param {?string} stav pokud je nenullový, tak ignoruje korektury v jiném stavu
|
||||||
|
*/
|
||||||
function dalsi_nebo_predchozi_korektura(dalsi=true, stav=null) {
|
function dalsi_nebo_predchozi_korektura(dalsi=true, stav=null) {
|
||||||
let predchozi = null;
|
let predchozi = null;
|
||||||
for (const strana of setrizene_strany) {
|
for (const strana of setrizene_strany) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{# Template starající se o editační/přidávací formulář. #}
|
||||||
<div id="korekturovaci-formular-div" style="display: none">
|
<div id="korekturovaci-formular-div" style="display: none">
|
||||||
<input size="24" name="au" value="{{user.first_name}} {{user.last_name}}" readonly/>
|
<input size="24" name="au" value="{{user.first_name}} {{user.last_name}}" readonly/>
|
||||||
<button type="button" id="korekturovaci-formular-odesli">Oprav!</button>
|
<button type="button" id="korekturovaci-formular-odesli">Oprav!</button>
|
||||||
|
@ -14,7 +15,39 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/** V podstatě singleton (viz korekturovaci_formular) starající se o editační/přidávací formulář. */
|
||||||
class _KorekturovaciFormular {
|
class _KorekturovaciFormular {
|
||||||
|
/**
|
||||||
|
* <div> obsahující celý formulář.
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
div;
|
||||||
|
/**
|
||||||
|
* Políčko, kam uživatel vyplňuje text.
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
text;
|
||||||
|
/**
|
||||||
|
* Tlačítko odeslat. Často ho chceme disablenout.
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
odesilaci_button;
|
||||||
|
/**
|
||||||
|
* <div> obsahující všechny tagy, pomocí tagy.getElementsByTagName("button") umíme dělat operace nad všemi tagy.
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
tagy;
|
||||||
|
/**
|
||||||
|
* Text upozorňující na to, že tagy nepřidáváme, ale editujeme. (Tj. chceme ho schovat, když vytváříme novou korekturu.)
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
tagy_info;
|
||||||
|
/**
|
||||||
|
* zda při přidávání nové korektury mají být všechny tagy odvybrané, nebo mají kopírovat předchozí nastavení
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
pri_otevreni_odvyber_tagy;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.div = document.getElementById('korekturovaci-formular-div');
|
this.div = document.getElementById('korekturovaci-formular-div');
|
||||||
this.text = document.getElementById('korekturovaci-formular-text');
|
this.text = document.getElementById('korekturovaci-formular-text');
|
||||||
|
@ -36,18 +69,28 @@
|
||||||
this.pri_otevreni_odvyber_tagy = true;
|
this.pri_otevreni_odvyber_tagy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Přepne tag na vybraný/nevybraný (v závislosti na tom, zda byl nevybrán/vybrán)
|
||||||
|
* @param {MouseEvent} event vyvolaný kliknutím na daný tag (musí mít za event.target daný tag)
|
||||||
|
*/
|
||||||
vyber_nebo_odvyber_tag(event) {
|
vyber_nebo_odvyber_tag(event) {
|
||||||
const button = event.target;
|
const button = event.target;
|
||||||
button.dataset.vybran = String(button.dataset.vybran === "false");
|
button.dataset.vybran = String(button.dataset.vybran === "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Nastaví všechny tagy na nevybrané. */
|
||||||
odvyber_tagy() { for (const tag of this.tagy.getElementsByTagName("button")) tag.dataset.vybran = "false"; }
|
odvyber_tagy() { for (const tag of this.tagy.getElementsByTagName("button")) tag.dataset.vybran = "false"; }
|
||||||
|
|
||||||
|
|
||||||
// schová korekturovací formulář
|
/** Schová (zavře) korekturovací formulář */
|
||||||
schovej() { this.div.style.display = 'none'; }
|
schovej() { this.div.style.display = 'none'; }
|
||||||
|
|
||||||
// zobrazí korekturovací formulář
|
/**
|
||||||
|
* Zobrazí/otevře korekturovací formulář (bez toho, aby v něm cokoliv měnil).
|
||||||
|
* @param {Strana} strana (na které straně se má zobrazit)
|
||||||
|
* @param {number} x
|
||||||
|
* @param {number} y
|
||||||
|
*/
|
||||||
_zobraz(strana, x, y) {
|
_zobraz(strana, x, y) {
|
||||||
this.odesilaci_button.disabled = false;
|
this.odesilaci_button.disabled = false;
|
||||||
this.div.style.display = 'block';
|
this.div.style.display = 'block';
|
||||||
|
@ -59,7 +102,15 @@
|
||||||
this.text.focus();
|
this.text.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill up comment form and show him
|
/**
|
||||||
|
* Předvyplní správně korekturovací formulář a zobrazí/otevře ho
|
||||||
|
* @param {Strana} strana (na které straně se má zobrazit)
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
* @param {string} text (text k předvyplněný, místo null chceš psáť "")
|
||||||
|
* @param {Number} komentar_id (!= -1 znamená úprava komentáře, -1 znamená přidávání korektury/komentáře)
|
||||||
|
* @param {Number} korektura_id (v případě komentar_id != -1 znamená: -1 je nová korektura, ne-1 je nový komentář)
|
||||||
|
*/
|
||||||
zobraz(strana, x, y, text, korektura_id=-1, komentar_id=-1) {
|
zobraz(strana, x, y, text, korektura_id=-1, komentar_id=-1) {
|
||||||
if (this.div.style.display !== 'none' && this.text.value !== "" && !confirm("Zavřít předchozí okénko přidávání korektury / editace komentáře?")) return;
|
if (this.div.style.display !== 'none' && this.text.value !== "" && !confirm("Zavřít předchozí okénko přidávání korektury / editace komentáře?")) return;
|
||||||
|
|
||||||
|
@ -85,6 +136,7 @@
|
||||||
this._zobraz(strana, x, y);
|
this._zobraz(strana, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shrábne data a pošle daný požadavek, čímž kromě vyřízení dané věci aktualizuje korektury+komentáře. */
|
||||||
odesli_formular() {
|
odesli_formular() {
|
||||||
this.odesilaci_button.disabled = true;
|
this.odesilaci_button.disabled = true;
|
||||||
const data = new FormData(CSRF_FORM);
|
const data = new FormData(CSRF_FORM);
|
||||||
|
@ -106,5 +158,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Objekt starající se o editační/přidávací formulář (jeho předvyplňování, zobrazování a posílání).
|
||||||
|
* @type {_KorekturovaciFormular}
|
||||||
|
*/
|
||||||
const korekturovaci_formular = new _KorekturovaciFormular();
|
const korekturovaci_formular = new _KorekturovaciFormular();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{# Template starající se o jeden každý komentář u korektury. #}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
<div class='comment' id='prekomentar' {# id='k{{k.id}}' #}>
|
<div class='comment' id='prekomentar' {# id='k{{k.id}}' #}>
|
||||||
|
@ -24,25 +25,57 @@
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* Prototyp komentáře, ze kterého se vygeneruje každý komentář (resp. jeho HTML reprezentace) v dokumentu
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
const prekomentar = document.getElementById('prekomentar');
|
const prekomentar = document.getElementById('prekomentar');
|
||||||
|
/**
|
||||||
|
* Mapování ID |-> komentář
|
||||||
|
* @type {Object.<Number, Komentar>}
|
||||||
|
*/
|
||||||
const komentare = {};
|
const komentare = {};
|
||||||
|
|
||||||
|
/** Třída reprezentující jeden komentář (a starající se o vytvoření a updatování jeho HTML reprezentace) */
|
||||||
class Komentar {
|
class Komentar {
|
||||||
|
/**
|
||||||
|
* Z dat aktualizuje (v případě, že korektura s daným ID existuje) nebo vytvoří Komentar
|
||||||
|
* @param {Object.<string, ?>} komentar_data „Slovník“ obsahující data daného komentáře
|
||||||
|
* @param {Korektura} korektura ke které se komentář má připojit
|
||||||
|
*/
|
||||||
static aktualizuj_nebo_vytvor(komentar_data, korektura) {
|
static aktualizuj_nebo_vytvor(komentar_data, korektura) {
|
||||||
const id = komentar_data['id'];
|
const id = komentar_data['id'];
|
||||||
if (id in komentare) komentare[id].aktualizuj(komentar_data);
|
if (id in komentare) komentare[id].aktualizuj(komentar_data);
|
||||||
else new Komentar(komentar_data, korektura);
|
else new Komentar(komentar_data, korektura);
|
||||||
}
|
}
|
||||||
|
|
||||||
#autor; #text;
|
/**
|
||||||
|
* <div> se jménem autora komentáře
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
#autor;
|
||||||
|
/**
|
||||||
|
* <div> obsahující text komentáře
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
#text;
|
||||||
|
/**
|
||||||
|
* <div> reprezentující celý komentář
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
htmlElement;
|
htmlElement;
|
||||||
id; korektura; {# komentar_data; #}
|
|
||||||
|
/** @type {Number} */
|
||||||
|
id;
|
||||||
|
/** @type{Korektura} */
|
||||||
|
korektura;
|
||||||
|
/** @type{string} */
|
||||||
autor;
|
autor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Vytvoří HTML reprezentaci, připojí komentář pod korekturu, nastaví event-listenery, uloží si data
|
||||||
* @param komentar_data
|
* @param {Object.<string, ?>} komentar_data „Slovník“ obsahující data daného komentáře
|
||||||
* @param {Korektura} korektura
|
* @param {Korektura} korektura korektura ke které se komentář má připojit
|
||||||
*/
|
*/
|
||||||
constructor(komentar_data, korektura) {
|
constructor(komentar_data, korektura) {
|
||||||
this.htmlElement = prekomentar.cloneNode(true);
|
this.htmlElement = prekomentar.cloneNode(true);
|
||||||
|
@ -63,28 +96,38 @@
|
||||||
komentare[this.id] = this;
|
komentare[this.id] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualizuje/nastaví JS data i HTML reprezentaci komentáře
|
||||||
|
* @param {Object.<string, ?>} komentar_data „Slovník“ obsahující data daného komentáře
|
||||||
|
*/
|
||||||
aktualizuj(komentar_data) {
|
aktualizuj(komentar_data) {
|
||||||
{# this.komentar_data = komentar_data; #}
|
|
||||||
this.set_autor(komentar_data['autor']);
|
this.set_autor(komentar_data['autor']);
|
||||||
this.set_text(komentar_data['text']);
|
this.set_text(komentar_data['text']);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualizuje/nastaví JS data i HTML reprezentaci autora komentáře
|
||||||
|
* @param {String} autor
|
||||||
|
*/
|
||||||
set_autor(autor) {
|
set_autor(autor) {
|
||||||
this.#autor.textContent=autor;
|
this.#autor.textContent=autor;
|
||||||
this.autor = autor;
|
this.autor = autor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} text
|
||||||
|
*/
|
||||||
set_text(text) {
|
set_text(text) {
|
||||||
this.#text.innerHTML=text;
|
this.#text.innerHTML=text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Ukaž formulář na editaci komentáře (když je zmáčknuto „uprav-komentar“)
|
/** Ukáže formulář na editaci komentáře (když je zmáčknuto „uprav-komentar“) */
|
||||||
#uprav_komentar() {
|
#uprav_komentar() {
|
||||||
return korekturovaci_formular.zobraz(this.korektura.strana, this.korektura.x, this.korektura.y, this.#text.textContent, this.korektura.id, this.id);
|
return korekturovaci_formular.zobraz(this.korektura.strana, this.korektura.x, this.korektura.y, this.#text.textContent, this.korektura.id, this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smaž komentář (když je zmáčknuto „smaz-komentar“)
|
/** Smaže komentář (když je zmáčknuto „smaz-komentar“) */
|
||||||
#smaz_komentar() {
|
#smaz_komentar() {
|
||||||
if (confirm('Opravdu smazat komentář?')) {
|
if (confirm('Opravdu smazat komentář?')) {
|
||||||
const data = new FormData(CSRF_FORM);
|
const data = new FormData(CSRF_FORM);
|
||||||
|
@ -99,7 +142,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smaž div komentáře, když je smazán komentář nebo jeho nadřazená korektura
|
/** Smaže div komentáře (ne databázový záznam!), používá se, když je smazán komentář nebo jeho nadřazená korektura */
|
||||||
smaz_pouze_na_strance() {
|
smaz_pouze_na_strance() {
|
||||||
delete komentare[this.id];
|
delete komentare[this.id];
|
||||||
this.htmlElement.remove();
|
this.htmlElement.remove();
|
||||||
|
|
|
@ -58,22 +58,75 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* Prototyp korektury, ze kterého se vygeneruje každý komentář (resp. jeho HTML reprezentace) v dokumentu
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
const prekorektura = document.getElementById('prekorektura');
|
const prekorektura = document.getElementById('prekorektura');
|
||||||
|
/**
|
||||||
|
* Prototyp pointeru (té lomené čáry od korektury)
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
const prepointer = document.getElementById('prepointer');
|
const prepointer = document.getElementById('prepointer');
|
||||||
|
/**
|
||||||
|
* Mapování ID |-> korektura
|
||||||
|
* @type {Object.<Number, Korektura>}
|
||||||
|
*/
|
||||||
const korektury = {};
|
const korektury = {};
|
||||||
|
|
||||||
|
/** Třída reprezentující jednu korekturu (a starající se o vytvoření a updatování její HTML reprezentace) */
|
||||||
class Korektura {
|
class Korektura {
|
||||||
|
/**
|
||||||
|
* Z dat aktualizuje (v případě, že korektura s daným ID existuje) nebo vytvoří Korekturu
|
||||||
|
* @param {Object.<string, ?>} korektura_data „Slovník“ obsahující data dané korektury
|
||||||
|
* @returns {Korektura} vytvořená/aktualizovaná Korektura (pro použití při vytváření/aktualizaci komentářů)
|
||||||
|
*/
|
||||||
static aktualizuj_nebo_vytvor(korektura_data) {
|
static aktualizuj_nebo_vytvor(korektura_data) {
|
||||||
const id = korektura_data['id'];
|
const id = korektura_data['id'];
|
||||||
if (id in korektury) return korektury[id].aktualizuj(korektura_data);
|
if (id in korektury) return korektury[id].aktualizuj(korektura_data);
|
||||||
else return new Korektura(korektura_data);
|
else return new Korektura(korektura_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#komentare; #tagy;
|
/**
|
||||||
htmlElement; pointer;
|
* <div> obsahující <div>y komentářů
|
||||||
id; x; y; strana; stav; sbalena = false; {# korektura_data; #}
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
#komentare;
|
||||||
|
/**
|
||||||
|
* <div> obsahující tagy
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
#tagy;
|
||||||
|
/**
|
||||||
|
* <div> reprezentující celý korekturu
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
htmlElement;
|
||||||
|
/**
|
||||||
|
* <div> reprezentující pointer (tu lomenou čáru od korektury)
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
pointer;
|
||||||
|
|
||||||
|
/** @type {Number} */
|
||||||
|
id;
|
||||||
|
/** @type {Number} */
|
||||||
|
x;
|
||||||
|
/** @type {Number} */
|
||||||
|
y;
|
||||||
|
/** @type {Strana} */
|
||||||
|
strana;
|
||||||
|
/** @type {string} */
|
||||||
|
stav;
|
||||||
|
/** @type {boolean} */
|
||||||
|
sbalena = false;
|
||||||
|
/** @type Set<Number> */
|
||||||
tagy;
|
tagy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vytvoří HTML reprezentaci, připojí korekturu pod stranu (ale neumístí ji), nastaví event-listenery, uloží si data
|
||||||
|
* @param {Object.<string, ?>} korektura_data „Slovník“ obsahující data dané korektury
|
||||||
|
*/
|
||||||
constructor(korektura_data) {
|
constructor(korektura_data) {
|
||||||
this.htmlElement = prekorektura.cloneNode(true);
|
this.htmlElement = prekorektura.cloneNode(true);
|
||||||
this.pointer = prepointer.cloneNode(true);
|
this.pointer = prepointer.cloneNode(true);
|
||||||
|
@ -109,12 +162,25 @@
|
||||||
korektury[this.id] = this;
|
korektury[this.id] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualizuje/nastaví JS data i HTML reprezentaci korektury
|
||||||
|
* @param {Object.<string, ?>} korektura_data „Slovník“ obsahující data dané korektury
|
||||||
|
* @returns {Korektura} pro jednodušší implementaci aktualizuj_nebo_vytvor vracíme this
|
||||||
|
*/
|
||||||
aktualizuj(korektura_data) {
|
aktualizuj(korektura_data) {
|
||||||
{# this.korektura_data = korektura_data; #}
|
|
||||||
this.set_stav(korektura_data['status']);
|
this.set_stav(korektura_data['status']);
|
||||||
|
this.set_tagy(korektura_data["tagy"]);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualizuje/nastaví JS data i HTML reprezentaci tagů korektury
|
||||||
|
* @param {Object.<string, ?>[]} tagy
|
||||||
|
*/
|
||||||
|
set_tagy(tagy) {
|
||||||
this.#tagy.innerHTML = "";
|
this.#tagy.innerHTML = "";
|
||||||
this.tagy = new Set();
|
this.tagy = new Set();
|
||||||
for (const tag of korektura_data["tagy"]) {
|
for (const tag of tagy) {
|
||||||
this.tagy.add(tag["id"]);
|
this.tagy.add(tag["id"]);
|
||||||
const span = document.createElement("span");
|
const span = document.createElement("span");
|
||||||
span.innerHTML = tag["nazev"];
|
span.innerHTML = tag["nazev"];
|
||||||
|
@ -122,32 +188,44 @@
|
||||||
span.style.backgroundColor = tag["barva"];
|
span.style.backgroundColor = tag["barva"];
|
||||||
this.#tagy.appendChild(span);
|
this.#tagy.appendChild(span);
|
||||||
}
|
}
|
||||||
return this;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualizuje/nastaví JS data i HTML reprezentaci stavu korektury
|
||||||
|
* @param {String} stav
|
||||||
|
*/
|
||||||
set_stav(stav) {
|
set_stav(stav) {
|
||||||
this.stav = stav;
|
this.stav = stav;
|
||||||
this.htmlElement.dataset.stav_korektury=stav;
|
this.htmlElement.dataset.stav_korektury=stav;
|
||||||
this.pointer.dataset.stav_korektury=stav;
|
this.pointer.dataset.stav_korektury=stav;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Přidá HTML reprezentaci komentáře pod tuto korekturu
|
||||||
|
* @param {HTMLElement} htmlElement přidávaný komentář (jako HTML prvek)
|
||||||
|
*/
|
||||||
pridej_htmlElement_komentare(htmlElement) { this.#komentare.appendChild(htmlElement); }
|
pridej_htmlElement_komentare(htmlElement) { this.#komentare.appendChild(htmlElement); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Sbalí/rozbalí (podle toho, zda byla rozbalená/sbalená) korekturu, ale nezmění pozice korektur (je třeba později zavolat umisti_korektury()) */
|
||||||
sbal_nebo_rozbal() {
|
sbal_nebo_rozbal() {
|
||||||
this.sbalena = !this.sbalena;
|
this.sbalena = !this.sbalena;
|
||||||
this.htmlElement.dataset.korektura_sbalena = String(this.sbalena);
|
this.htmlElement.dataset.korektura_sbalena = String(this.sbalena);
|
||||||
}
|
}
|
||||||
|
/** Doplněk sbal_nebo_rozbal, který i přeskládá korektury. */
|
||||||
#sbal_nebo_rozbal(){
|
#sbal_nebo_rozbal(){
|
||||||
this.sbal_nebo_rozbal();
|
this.sbal_nebo_rozbal();
|
||||||
umisti_korektury()
|
umisti_korektury();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ukaž komentovací formulář (když je zmáčknuto komentovat)
|
/** Ukaž komentovací formulář (když je zmáčknuto komentovat) */
|
||||||
#komentuj() { korekturovaci_formular.zobraz(this.strana, this.x, this.y, "", this.id); }
|
#komentuj() { korekturovaci_formular.zobraz(this.strana, this.x, this.y, "", this.id); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Změní stav (když je zmáčknuto tlačítko daného stavu)
|
||||||
|
* @param {MouseEvent} event který vyvolal danou změnu (event.target.value musí být chtěný stav)
|
||||||
|
*/
|
||||||
#zmen_stav_korektury(event) {
|
#zmen_stav_korektury(event) {
|
||||||
const data = new FormData(CSRF_FORM);
|
const data = new FormData(CSRF_FORM);
|
||||||
data.append('id', this.id);
|
data.append('id', this.id);
|
||||||
|
@ -164,6 +242,7 @@
|
||||||
.catch(error => {alert('Něco se nepovedlo:' + error);});
|
.catch(error => {alert('Něco se nepovedlo:' + error);});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Smaže korekturu (když je zmáčknuto „smaz-korekturu“) */
|
||||||
#smaz_korekturu() {
|
#smaz_korekturu() {
|
||||||
if (confirm('Opravdu smazat korekturu?')) {
|
if (confirm('Opravdu smazat korekturu?')) {
|
||||||
const data = new FormData(CSRF_FORM);
|
const data = new FormData(CSRF_FORM);
|
||||||
|
@ -180,6 +259,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Smaže div korektury (včetně všech komentářů; ne databázový záznam!) */
|
||||||
#smaz_pouze_na_strance() {
|
#smaz_pouze_na_strance() {
|
||||||
this.strana.korektury.splice(this.strana.korektury.indexOf(this), 1);
|
this.strana.korektury.splice(this.strana.korektury.indexOf(this), 1);
|
||||||
delete korektury[this.id];
|
delete korektury[this.id];
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{# Template starající se o tlačítkovou lištu nahoře, tj. hlavně o hromadné schovávání korektur. #}
|
||||||
Zobrazit:
|
Zobrazit:
|
||||||
<input type="checkbox" id="k_oprave_checkbox" checked>
|
<input type="checkbox" id="k_oprave_checkbox" checked>
|
||||||
<label for="k_oprave_checkbox">K opravě (<span id="k_oprave_pocet">↺</span>)</label>
|
<label for="k_oprave_checkbox">K opravě (<span id="k_oprave_pocet">↺</span>)</label>
|
||||||
|
@ -30,6 +31,10 @@ Zobrazit:
|
||||||
umisti_korektury();
|
umisti_korektury();
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Změní CSS tak, aby se korektury příslušného stavu nezobrazovali/zobrazovali (v závislosti na tom, jestli byly zobrazené/nezobrazené)
|
||||||
|
* @param {string} aclass stav korektur, které mají být skryty/zobrazeny
|
||||||
|
*/
|
||||||
function skryj_nebo_zobraz_korektury(aclass)
|
function skryj_nebo_zobraz_korektury(aclass)
|
||||||
{
|
{
|
||||||
const stylesheets = document.styleSheets;
|
const stylesheets = document.styleSheets;
|
||||||
|
@ -56,6 +61,11 @@ Zobrazit:
|
||||||
umisti_korektury();
|
umisti_korektury();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapování stav korektur |-> span, kde se píše, kolik je korektur toho stavu.
|
||||||
|
* Používané v následující funcki
|
||||||
|
* @type {Object.<string, HTMLElement>}
|
||||||
|
*/
|
||||||
const spany_s_pocty_stavu_korektur = {
|
const spany_s_pocty_stavu_korektur = {
|
||||||
'k_oprave': document.getElementById('k_oprave_pocet'),
|
'k_oprave': document.getElementById('k_oprave_pocet'),
|
||||||
'opraveno': document.getElementById('opraveno_pocet'),
|
'opraveno': document.getElementById('opraveno_pocet'),
|
||||||
|
@ -63,6 +73,7 @@ Zobrazit:
|
||||||
'k_zaneseni': document.getElementById('k_zaneseni_pocet'),
|
'k_zaneseni': document.getElementById('k_zaneseni_pocet'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Aktualizuje počty korektur jednotlivých stavů */
|
||||||
function aktualizuj_pocty_stavu() {
|
function aktualizuj_pocty_stavu() {
|
||||||
const pocty_stavu_korektur = {};
|
const pocty_stavu_korektur = {};
|
||||||
for (const stav_korektury of Object.keys(spany_s_pocty_stavu_korektur)) pocty_stavu_korektur[stav_korektury] = 0;
|
for (const stav_korektury of Object.keys(spany_s_pocty_stavu_korektur)) pocty_stavu_korektur[stav_korektury] = 0;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{# Template starající se o zobrazení PDF stran a o umístění korektur na ně. (O samotné korektury se stará `./korektura.html`.) #}
|
||||||
{% for i in indexy_stran %}
|
{% for i in indexy_stran %}
|
||||||
<div class='imgdiv'>
|
<div class='imgdiv'>
|
||||||
<img
|
<img
|
||||||
|
@ -19,14 +20,40 @@
|
||||||
const MINIMALNI_VYSKA_POINTERU = 30;
|
const MINIMALNI_VYSKA_POINTERU = 30;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Mapování index_strany |-> strana
|
||||||
* @type {Object.<int, Strana>}
|
* @type {Object.<int, Strana>}
|
||||||
*/
|
*/
|
||||||
const strany = {};
|
const strany = {};
|
||||||
|
|
||||||
|
/** Třída spravující jednu stranu PDF a umisťující na ni příslušné korektury. */
|
||||||
class Strana {
|
class Strana {
|
||||||
htmlElement_img; htmlElement_div;
|
/**
|
||||||
id; korektury;
|
* <img> příslušící straně
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
htmlElement_img;
|
||||||
|
/**
|
||||||
|
* <div> obalující stranu, do něj se umisťují korektury
|
||||||
|
* @type {HTMLElement}
|
||||||
|
*/
|
||||||
|
htmlElement_div;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index strany (používá se při ukládání korektury (a načítání <img>))
|
||||||
|
* @type {Number}
|
||||||
|
*/
|
||||||
|
id;
|
||||||
|
/**
|
||||||
|
* Korektury na příslušné straně (BÚNO setříděné podle vertikálního umístění)
|
||||||
|
* @type {Korektura[]}
|
||||||
|
*/
|
||||||
|
korektury;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uloží si data (včetně pointrů na správné části HTML DOMu) a nastaví event-listener
|
||||||
|
* @param {HTMLElement} htmlElement_img
|
||||||
|
*/
|
||||||
constructor(htmlElement_img) {
|
constructor(htmlElement_img) {
|
||||||
this.htmlElement_img = htmlElement_img;
|
this.htmlElement_img = htmlElement_img;
|
||||||
this.htmlElement_div = this.htmlElement_img.parentNode;
|
this.htmlElement_div = this.htmlElement_img.parentNode;
|
||||||
|
@ -39,6 +66,10 @@
|
||||||
strany[this.id] = this;
|
strany[this.id] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Otevře korekturovací formulář pro přidání korektury v daném místě
|
||||||
|
* @param {MouseEvent} event
|
||||||
|
*/
|
||||||
#korekturuj(event) {
|
#korekturuj(event) {
|
||||||
switch (document.body.dataset.stav_pdf) {
|
switch (document.body.dataset.stav_pdf) {
|
||||||
case 'zanaseni':
|
case 'zanaseni':
|
||||||
|
@ -61,8 +92,10 @@
|
||||||
console.log("Pro přesun korektur: strana = " + this.id + ", x = " + dx + ", y = " + dy);
|
console.log("Pro přesun korektur: strana = " + this.id + ", x = " + dx + ", y = " + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Setřídí seznam korektur příslušný dané straně */
|
||||||
setrid_korektury() { this.korektury.sort((a, b) => a.y - b.y); }
|
setrid_korektury() { this.korektury.sort((a, b) => a.y - b.y); }
|
||||||
|
|
||||||
|
/** Zobrazí korektury a jejich pointry (a umístí je správně pod sebe) na dané straně */
|
||||||
umisti_korektury() {
|
umisti_korektury() {
|
||||||
this.setrid_korektury()
|
this.setrid_korektury()
|
||||||
|
|
||||||
|
@ -98,11 +131,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vytvoření objektu Strana pro každou stranu
|
||||||
for (const strana_img of document.getElementsByClassName('strana'))
|
for (const strana_img of document.getElementsByClassName('strana'))
|
||||||
new Strana(strana_img);
|
new Strana(strana_img);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seznam stran setřízený podle toho, jak jdou po sobě (aby se dali korektury prohledávat od první na HTML stránce po poslední)
|
||||||
|
* @type {Strana[]}
|
||||||
|
*/
|
||||||
const setrizene_strany = Object.values(strany);
|
const setrizene_strany = Object.values(strany);
|
||||||
setrizene_strany.sort((a, b) => a.htmlElement_img.offsetTop - b.htmlElement_img.offsetTop);
|
setrizene_strany.sort((a, b) => a.htmlElement_img.offsetTop - b.htmlElement_img.offsetTop);
|
||||||
|
|
||||||
|
/** Zobrazí korektury a jejich pointry (a umístí je správně pod sebe) na všech stranách */
|
||||||
function umisti_korektury() { for (const strana of Object.values(strany)) strana.umisti_korektury(); }
|
function umisti_korektury() { for (const strana of Object.values(strany)) strana.umisti_korektury(); }
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{# Template starající se o formulář na změnu stavu PDF (včetně jeho odeslání) #}
|
||||||
<b>Změnit stav PDF:</b>
|
<b>Změnit stav PDF:</b>
|
||||||
<br>
|
<br>
|
||||||
<form method="post" id="PDFSTAV_FORM">
|
<form method="post" id="PDFSTAV_FORM">
|
||||||
|
@ -12,12 +13,17 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* Formulář měnící stav korekturovaného PDF
|
||||||
|
* @type {HTMLFormElement}
|
||||||
|
*/
|
||||||
const pdfstav_form = document.getElementById('PDFSTAV_FORM');
|
const pdfstav_form = document.getElementById('PDFSTAV_FORM');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Fetchne stav korekturovaného PDF a změní ho na dané stránce.
|
||||||
* @param {RequestInit} data
|
* FIXME: nemění, který radio-button je vybrán.
|
||||||
* @param {Boolean} catchError
|
* @param {RequestInit} data FormData a jiné náležitosti (method: POST) posílané při změně stavu korekturovaného PDF
|
||||||
|
* @param {Boolean} catchError jestli padat hlasitě (pokud se aktualizuje automaticky a spadne to např. na nepřítomnost sítě, pak není třeba informovat uživatele)
|
||||||
*/
|
*/
|
||||||
function fetchStav(data, catchError=true) {
|
function fetchStav(data, catchError=true) {
|
||||||
fetch("{% url 'korektury_api_pdf_stav' korekturovanepdf.id %}", data
|
fetch("{% url 'korektury_api_pdf_stav' korekturovanepdf.id %}", data
|
||||||
|
|
Loading…
Reference in a new issue