update
This commit is contained in:
155
AzA march 2026/intern_portal/static/js/documents.js
Normal file
155
AzA march 2026/intern_portal/static/js/documents.js
Normal file
@@ -0,0 +1,155 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var cfg = window.AZA_DOC;
|
||||
if (!cfg) return;
|
||||
|
||||
var editor = document.getElementById("doc-editor");
|
||||
var titleEl = document.getElementById("doc-title");
|
||||
var categoryEl = document.getElementById("doc-category");
|
||||
var taskEl = document.getElementById("doc-task");
|
||||
var statusEl = document.getElementById("save-status");
|
||||
var saveBtn = document.getElementById("btn-save");
|
||||
var saving = false;
|
||||
var autoTimer = null;
|
||||
var lastSaved = "";
|
||||
|
||||
function setStatus(state, text) {
|
||||
statusEl.className = "save-status save-status-" + state;
|
||||
statusEl.textContent = text;
|
||||
}
|
||||
|
||||
function payloadSnapshot() {
|
||||
return JSON.stringify({
|
||||
title: titleEl.value,
|
||||
category: categoryEl.value,
|
||||
task: taskEl.value,
|
||||
html: editor.innerHTML,
|
||||
});
|
||||
}
|
||||
|
||||
function markDirty() {
|
||||
if (!saving) {
|
||||
setStatus("unsaved", "Nicht gespeicherte Änderungen");
|
||||
}
|
||||
clearTimeout(autoTimer);
|
||||
autoTimer = setTimeout(function () {
|
||||
saveDocument(false);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
function saveDocument(manual) {
|
||||
if (saving) return;
|
||||
var snap = payloadSnapshot();
|
||||
if (!manual && snap === lastSaved) {
|
||||
setStatus("saved", "Gespeichert");
|
||||
return;
|
||||
}
|
||||
saving = true;
|
||||
setStatus("saving", "Speichert...");
|
||||
|
||||
var fd = new FormData();
|
||||
fd.append("csrf_token", cfg.csrf);
|
||||
fd.append("title", titleEl.value.trim() || "Unbenanntes Dokument");
|
||||
fd.append("content_html", editor.innerHTML);
|
||||
fd.append("category", categoryEl.value);
|
||||
fd.append("task_id", taskEl.value);
|
||||
|
||||
fetch("/api/documents/" + cfg.id + "/save", {
|
||||
method: "POST",
|
||||
body: fd,
|
||||
credentials: "same-origin",
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (data) {
|
||||
saving = false;
|
||||
if (data.ok) {
|
||||
lastSaved = snap;
|
||||
setStatus("saved", "Gespeichert");
|
||||
} else {
|
||||
setStatus("error", "Fehler beim Speichern");
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
saving = false;
|
||||
setStatus("error", "Fehler beim Speichern");
|
||||
});
|
||||
}
|
||||
|
||||
function findListItem(node) {
|
||||
var el = node && node.nodeType === 3 ? node.parentElement : node;
|
||||
while (el && el !== editor) {
|
||||
if (el.tagName === "LI") return el;
|
||||
el = el.parentElement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function isEmptyListItem(li) {
|
||||
if (!li) return false;
|
||||
var text = (li.textContent || "").replace(/\u00a0/g, " ").replace(/\u200B/g, "").trim();
|
||||
return text === "";
|
||||
}
|
||||
|
||||
editor.addEventListener("keydown", function (e) {
|
||||
if (e.key !== "Enter" || e.shiftKey) return;
|
||||
var li = findListItem(window.getSelection().anchorNode);
|
||||
if (!li) return;
|
||||
if (isEmptyListItem(li)) {
|
||||
e.preventDefault();
|
||||
document.execCommand("outdent");
|
||||
if (findListItem(window.getSelection().anchorNode) && isEmptyListItem(findListItem(window.getSelection().anchorNode))) {
|
||||
document.execCommand("outdent");
|
||||
}
|
||||
var p = document.createElement("p");
|
||||
p.appendChild(document.createElement("br"));
|
||||
var parent = li.parentElement;
|
||||
if (parent && (parent.tagName === "UL" || parent.tagName === "OL") && parent.children.length === 1) {
|
||||
parent.replaceWith(p);
|
||||
} else {
|
||||
li.replaceWith(p);
|
||||
}
|
||||
var sel = window.getSelection();
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(p);
|
||||
range.collapse(true);
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
markDirty();
|
||||
}
|
||||
});
|
||||
|
||||
[titleEl, categoryEl, taskEl].forEach(function (el) {
|
||||
el.addEventListener("input", markDirty);
|
||||
el.addEventListener("change", markDirty);
|
||||
});
|
||||
|
||||
editor.addEventListener("input", markDirty);
|
||||
|
||||
saveBtn.addEventListener("click", function () {
|
||||
clearTimeout(autoTimer);
|
||||
saveDocument(true);
|
||||
});
|
||||
|
||||
document.querySelectorAll(".doc-tb-btn").forEach(function (btn) {
|
||||
btn.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
var cmd = btn.getAttribute("data-cmd");
|
||||
var val = btn.getAttribute("data-value");
|
||||
editor.focus();
|
||||
if (cmd === "link") {
|
||||
var url = window.prompt("Link-URL (https://...):", "https://");
|
||||
if (url && !url.toLowerCase().startsWith("javascript:")) {
|
||||
document.execCommand("createLink", false, url);
|
||||
}
|
||||
} else if (cmd === "formatBlock" && val) {
|
||||
document.execCommand(cmd, false, val);
|
||||
} else {
|
||||
document.execCommand(cmd, false, null);
|
||||
}
|
||||
markDirty();
|
||||
});
|
||||
});
|
||||
|
||||
lastSaved = payloadSnapshot();
|
||||
})();
|
||||
Reference in New Issue
Block a user