135 lines
3.5 KiB
JavaScript
Executable File
135 lines
3.5 KiB
JavaScript
Executable File
// client.js
|
|
// UI: Buttons, Anzeige von Result als JSON + Baum, Fallback für Commands
|
|
|
|
function appendLog(line) {
|
|
const el = document.getElementById("log");
|
|
if (!el) return;
|
|
|
|
const now = new Date().toISOString();
|
|
el.value += `[${now}] ${line}\n`;
|
|
el.scrollTop = el.scrollHeight;
|
|
}
|
|
|
|
function clearTextarea(id) {
|
|
const el = document.getElementById(id);
|
|
if (el) el.value = "";
|
|
}
|
|
|
|
function clearElement(id) {
|
|
const el = document.getElementById(id);
|
|
if (el) el.innerHTML = "";
|
|
}
|
|
|
|
function formatScalar(value) {
|
|
if (value === null) return "null";
|
|
if (value === undefined) return "undefined";
|
|
if (typeof value === "string") return JSON.stringify(value);
|
|
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
if (typeof value === "boolean") return String(value);
|
|
return String(value);
|
|
}
|
|
|
|
function renderTree(container, value, key = "result", open = true) {
|
|
if (!container) return;
|
|
|
|
container.innerHTML = "";
|
|
container.appendChild(renderNode(key, value, open));
|
|
}
|
|
|
|
function renderNode(key, value, open = false) {
|
|
const isObject = value !== null && typeof value === "object";
|
|
|
|
if (!isObject) {
|
|
const leaf = document.createElement("div");
|
|
leaf.className = "tree-leaf";
|
|
leaf.textContent = `${key}: ${formatScalar(value)}`;
|
|
return leaf;
|
|
}
|
|
|
|
const details = document.createElement("details");
|
|
details.open = open;
|
|
|
|
const summary = document.createElement("summary");
|
|
summary.textContent = Array.isArray(value)
|
|
? `${key} [${value.length}]`
|
|
: key;
|
|
|
|
details.appendChild(summary);
|
|
|
|
const body = document.createElement("div");
|
|
body.style.marginLeft = "16px";
|
|
|
|
if (Array.isArray(value)) {
|
|
value.forEach((item, idx) => {
|
|
body.appendChild(renderNode(String(idx), item, false));
|
|
});
|
|
} else {
|
|
Object.entries(value).forEach(([childKey, childVal]) => {
|
|
body.appendChild(renderNode(childKey, childVal, false));
|
|
});
|
|
}
|
|
|
|
details.appendChild(body);
|
|
return details;
|
|
}
|
|
|
|
function renderResult(result) {
|
|
const jsonEl = document.getElementById("result-json");
|
|
const treeEl = document.getElementById("result-tree");
|
|
|
|
if (jsonEl) {
|
|
jsonEl.value = JSON.stringify(result, null, 2);
|
|
}
|
|
|
|
renderTree(treeEl, result, "result", true);
|
|
}
|
|
|
|
async function onCalculateClick() {
|
|
clearTextarea("analysis-log");
|
|
clearTextarea("result-json");
|
|
clearElement("result-tree");
|
|
|
|
appendLog("Starte Berechnung...");
|
|
|
|
try {
|
|
const result = await window.calculate();
|
|
renderResult(result);
|
|
appendLog("Result angezeigt.");
|
|
} catch (err) {
|
|
appendLog(`Fehler: ${err.message}`);
|
|
}
|
|
}
|
|
|
|
async function onCommandClick(btn) {
|
|
const cmd = btn.dataset.cmd;
|
|
const payloadSelector = btn.dataset.payload;
|
|
const payload = payloadSelector
|
|
? document.querySelector(payloadSelector)?.value ?? ""
|
|
: "";
|
|
|
|
if (typeof window.sendCommand === "function") {
|
|
try {
|
|
await window.sendCommand(cmd, payload);
|
|
appendLog(`Command gesendet: ${cmd}${payload ? " " + payload : ""}`);
|
|
} catch (err) {
|
|
appendLog(`Command-Fehler: ${err.message}`);
|
|
}
|
|
return;
|
|
}
|
|
|
|
appendLog(`Command (kein Transport definiert): ${cmd}${payload ? " " + payload : ""}`);
|
|
}
|
|
|
|
function setupUi() {
|
|
const calculateBtn = document.getElementById("btn-calculate");
|
|
if (calculateBtn) {
|
|
calculateBtn.addEventListener("click", onCalculateClick);
|
|
}
|
|
|
|
document.querySelectorAll("button[data-cmd]").forEach(btn => {
|
|
if (btn.id === "btn-calculate") return;
|
|
btn.addEventListener("click", () => onCommandClick(btn));
|
|
});
|
|
}
|
|
|
|
window.addEventListener("DOMContentLoaded", setupUi); |