Grotti 3.5.0: Pagination, Logging, Deb-Paket, Makro-Doku, PLA-Match-Fix.

This commit is contained in:
Dominic Gundel committed 2026-10-19 11:14:24 +02:00
1 parent 4ffe1dcfc6
commit f1f79c2ce2
38 files changed
+1062 -75

No files matched your search

+16 -3
View File
@@ -26,9 +26,12 @@
<div class="skeleton" style="height:4rem"></div>
<div class="skeleton" style="height:4rem"></div>
</div>
<div class="pager" id="tl-pager" hidden></div>
{% endblock %}
{% block script %}
<script>
let tlPage = 1;
let tlItems = [];
const KINDS = [
["queue", "Warteschlange"],
["ablauf", "Ablauf"],
@@ -111,14 +114,19 @@ function itemHtml(ev) {
function render(items) {
const box = document.getElementById("timeline");
const note = document.getElementById("tl-note");
if (!items.length) {
const pager = document.getElementById("tl-pager");
tlItems = items || [];
if (!tlItems.length) {
box.innerHTML = `<div class="card empty-state">${icon("activity")}<p>Keine Einträge${filter.range === "day" ? " heute" : ""}.</p>${
filter.range !== "all" ? `<button type="button" class="ghost" data-range-jump="all">Alle anzeigen</button>` : ""}</div>`;
note.textContent = "";
renderPager(pager, null, () => {});
return;
}
const paged = pageSlice(tlItems, tlPage, DEFAULT_PAGE_SIZE);
tlPage = paged.page;
const groups = [];
for (const ev of items) {
for (const ev of paged.items) {
const label = dayLabel(ev.created_at);
if (!groups.length || groups[groups.length - 1].label !== label) groups.push({ label, items: [] });
groups[groups.length - 1].items.push(ev);
@@ -126,7 +134,11 @@ function render(items) {
box.innerHTML = groups.map((g) =>
`<section class="tl-day"><h3>${escapeHtml(g.label)} · ${g.items.length}</h3><ol class="tl-list">${g.items.map(itemHtml).join("")}</ol></section>`
).join("");
note.textContent = items.length >= 300 ? "Die letzten 300 Einträge. Zeitraum oder Filter enger stellen für ältere." : "";
note.textContent = tlItems.length >= 300 ? "Die letzten 300 Einträge. Zeitraum oder Filter enger stellen für ältere." : "";
renderPager(pager, paged, (p) => {
tlPage = p;
render(tlItems);
});
}
async function load() {
@@ -137,6 +149,7 @@ async function load() {
if (filter.host) q.set("host", filter.host);
try {
const data = await api("/ereignisse?" + q.toString());
tlPage = 1;
render(data.items || []);
} catch (err) {
document.getElementById("timeline").innerHTML = `<div class="strip bad">${icon("alert")}<span>${escapeHtml(err.message)}</span></div>`;