diff --git a/public/client.js b/public/client.js index 39fb8da..1ddd5d5 100755 --- a/public/client.js +++ b/public/client.js @@ -84,16 +84,107 @@ function renderResult(result) { renderTree(treeEl, result, "result", true); } +async function fetchCSV() { + const res = await fetch("/api/latest-snapshot"); + if (!res.ok) throw new Error("Fehler beim Laden des Snapshots"); + + let data; + if (res.headers.get("content-type")?.includes("application/json")) { + data = await res.json(); + } else { + const csvData = await res.text(); + data = { + filename: "latest.csv", + mtime: new Date().toISOString(), + content: csvData + }; + } + + const lines = data.content.trim().split(/\r?\n/).filter(Boolean); + if (lines.length < 2) { + throw new Error("Keine oder unvollständige Daten"); + } + + const headers = lines[0].split(",").map(h => h.trim()); + + const rows = lines.slice(1).map(line => { + const cells = line.split(","); + const obj = {}; + headers.forEach((h, i) => { + const raw = (cells[i] ?? "").trim(); + const numeric = Number(raw); + obj[h] = raw !== "" && Number.isFinite(numeric) ? numeric : raw; + }); + return obj; + }); + + return { data, headers, rows }; +} + +async function renderSnapshot() { + const table = document.getElementById("snapshot-table"); + if (!table) return; + + try { + const { data, headers, rows } = await fetchCSV(); + + // Info anzeigen + const infoEl = document.getElementById("snapshot-info"); + if (infoEl) { + infoEl.textContent = `Datei: ${data.filename}, Geändert: ${new Date(data.mtime).toLocaleString()}, Zeilen: ${rows.length}`; + } + + // Tabelle leeren + table.innerHTML = ""; + + // Header + const thead = document.createElement("thead"); + const headerRow = document.createElement("tr"); + headers.forEach(h => { + const th = document.createElement("th"); + th.textContent = h; + headerRow.appendChild(th); + }); + thead.appendChild(headerRow); + table.appendChild(thead); + + // Body + const tbody = document.createElement("tbody"); + rows.forEach(row => { + const tr = document.createElement("tr"); + headers.forEach(h => { + const td = document.createElement("td"); + let value = row[h]; + if (typeof value === 'number') { + if (h === 'id' || h === 'seen_by') { + value = Math.round(value); + } else { + value = value.toFixed(1); + } + } + td.textContent = value; + tr.appendChild(td); + }); + tbody.appendChild(tr); + }); + table.appendChild(tbody); + } catch (err) { + console.error("Fehler beim Rendern des Snapshots:", err); + } +} + async function onCalculateClick() { clearTextarea("analysis-log"); clearTextarea("result-json"); clearElement("result-tree"); + clearElement("snapshot-table"); appendLog("Starte Berechnung..."); try { const result = await window.calculate(); renderResult(result); + await renderSnapshot(); appendLog("Result angezeigt."); } catch (err) { appendLog(`Fehler: ${err.message}`); diff --git a/public/index.html b/public/index.html index b7d76d1..bfb004c 100755 --- a/public/index.html +++ b/public/index.html @@ -74,7 +74,13 @@