Dynamické přidávání korektur a komentářů a úprava komentářů

This commit is contained in:
Jonas Havelka 2025-02-11 12:00:47 +01:00
parent 9ccacaecb5
commit 6eb4633af0
6 changed files with 106 additions and 61 deletions

View file

@ -58,7 +58,39 @@ class OpravaSerializer(serializers.ModelSerializer):
# komentar_set = serializers.ListField(child=KomentarSerializer())
def opravy_a_komentare_view(request, pdf_id: int, **kwargs):
q = request.POST
if request.method == 'POST':
q = request.POST
x = int(q.get('x'))
y = int(q.get('y'))
img_id = int(q.get('img_id'))
oprava_id = int(q.get('oprava_id'))
komentar_id = int(q.get('komentar_id'))
text = q.get('text')
# prirazeni autora podle prihlaseni
autor_user = request.user
# pokud existuje ucet (user), ale neni to organizator = 403
autor = Organizator.objects.filter(osoba__user=autor_user).first()
if komentar_id != -1:
komentar = get_object_or_404(Komentar, id=komentar_id)
komentar.text = text
komentar.autor = autor
komentar.save()
else:
if oprava_id != -1:
oprava = get_object_or_404(Oprava, id=oprava_id)
else:
pdf = get_object_or_404(KorekturovanePDF, id=pdf_id)
oprava = Oprava.objects.create(
pdf=pdf,
strana=img_id,
x=x,
y=y,
)
Komentar.objects.create(oprava=oprava, autor=autor, text=text)
opravy = Oprava.objects.filter(pdf=pdf_id).all()
# Serializovat list je prý security vulnerability, tedy je přidán slovník pro bezpečnost

View file

@ -1,64 +1,75 @@
<div id="commform-div" style="display: none">
<form action='' id="commform" method="POST">
{% csrf_token %}
<input size="24" name="au" value="{{user.first_name}} {{user.last_name}}" readonly/>
<input type=submit value="Oprav!"/>
<button type="button" onclick="close_commform()">Zavřít</button>
<br/>
<textarea id="commform-text" cols=40 rows=10 name="txt"></textarea>
<br/>
<input type="hidden" size="3" id="commform-x" name="x"/>
<input type="hidden" size="3" id="commform-y" name="y"/>
<input type="hidden" size="3" id="commform-img-id" name="img-id"/>
<input type="hidden" size="3" id="commform-id" name="id"/>
<input type="hidden" size="3" id="commform-action" name="action"/>
</form>
<input size="24" name="au" value="{{user.first_name}} {{user.last_name}}" readonly/>
<button id="commform-submit">Oprav!</button>
<button id="commform-close">Zavřít</button>
<br/>
<textarea id="commform-text" cols=40 rows=10 name="txt"></textarea>
<br/>
</div>
<script>
const commform = document.getElementById('commform');
commform._div = document.getElementById('commform-div');
commform._text = document.getElementById('commform-text');
commform._x = document.getElementById('commform-x');
commform._y = document.getElementById('commform-y');
commform._imgID = document.getElementById('commform-img-id');
commform._id = document.getElementById('commform-id');
commform._action = document.getElementById('commform-action');
class _CommForm {
constructor() {
this.div = document.getElementById('commform-div');
this.text = document.getElementById('commform-text');
const submit_button = document.getElementById('commform-submit');
const close_button = document.getElementById('commform-close');
// ctrl-enter submits form
commform._text.addEventListener("keydown", ev => {
if (ev.code === "Enter" && ev.ctrlKey) commform.submit();
});
//hide comment form
function close_commform() {
commform._div.style.display = 'none';
return false;
// ctrl-enter submits form
this.text.addEventListener("keydown", ev => {
if (ev.code === "Enter" && ev.ctrlKey) this.submit();
});
close_button.addEventListener("click", _ => { this.close(); });
submit_button.addEventListener("click", _ => { this.submit(); });
}
// schová commform
close() { this.div.style.display = 'none'; }
// zobrazí commform (bez vyplňování)
_show(img_id, x, y) {
this.div.style.display = 'block';
this.div.style.left = x;
this.div.style.top = y;
const img = document.getElementById("img-" + img_id);
img.parentNode.appendChild(commform.div);
this.text.focus();
}
// fill up comment form and show him
show(img_id, x, y, text, oprava_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;
// set hidden values
this.x = x;
this.y = y;
this.imgID = img_id;
this.oprava_id = oprava_id;
this.komentar_id = komentar_id;
this.text.value = text;
// show form
this._show(img_id, x, y);
}
submit() {
const data = new FormData(CSRF_FORM);
data.append('x', this.x);
data.append('y', this.y);
data.append('img_id', this.imgID);
data.append('oprava_id', this.oprava_id);
data.append('komentar_id', this.komentar_id);
data.append('text', this.text.value);
update_all({method: 'POST', body: data}, true, () => {this.close()});
}
}
//fill up comment form and show him
function show_form(img_id, dx, dy, id, text, action) {
const img = document.getElementById("img-" + img_id);
if (commform._div.style.display !== 'none' && commform._text.value !== "" && !confirm("Zavřít předchozí okénko přidávání korektury / editace komentáře?")) return 1;
// set hidden values
commform._x.value = dx;
commform._y.value = dy;
commform._imgID.value = img_id;
commform._id.value = id;
commform._action.value = action;
commform._text.value = text;
// show form
commform._div.style.display = 'block';
commform._div.style.left = dx;
commform._div.style.top = dy;
img.parentNode.appendChild(commform._div);
commform._text.focus();
return true;
}
const commform = new _CommForm();
</script>

View file

@ -74,7 +74,7 @@
// show comment form when 'update-comment' button pressed
#update_comment() {
return show_form(this.oprava.img_id, this.oprava.x, this.oprava.y, this.id, this.#text.textContent, 'update-comment');
return commform.show(this.oprava.img_id, this.oprava.x, this.oprava.y, this.#text.textContent, -1, this.id);
}
#delete_comment() {

View file

@ -121,7 +121,7 @@
}
// show comment form, when 'comment' button pressed
#comment() { return show_form(this.img_id, this.x, this.y, this.id, "", "comment"); }
#comment() { commform.show(this.img_id, this.x, this.y, "", this.id); }
#zmenStavKorektury(event) {
const data = new FormData(CSRF_FORM);

View file

@ -43,8 +43,8 @@
dx = ev.offsetX;
dy = ev.offsetY;
}
const img_id = image.id;
return show_form(img_id, dx, dy, '', '', '');
const img_id = image.id.substring(4);
commform.show(img_id, dx, dy, '');
});
}
</script>

View file

@ -11,12 +11,14 @@
*
* @param {RequestInit} data
* @param {Boolean} catchError
* @param pri_uspechu Akce, která se má provést při úspěchu (speciálně zavřít formulář)
*/
function update_all(data={}, catchError=true) { // FIXME není mi jasné, zda v {} nemá být `cache: "no-store"`, aby prohlížeč necachoval GET.
function update_all(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" pdf.id %}', data)
.then(response => {
if (!response.ok && catchError) {alert('Něco se nepovedlo:' + response.statusText);}
else response.json().then(data => {
if (pri_uspechu) pri_uspechu();
for (const oprava_data of data["context"]) {
const oprava = Oprava.update_or_create(oprava_data);
for (const komentar_data of oprava_data["komentare"]) {