From f81942f22874326263dfa99c0e2cc5ebcc614ce9 Mon Sep 17 00:00:00 2001 From: bahmcloud Date: Wed, 14 Jan 2026 17:11:15 +0000 Subject: [PATCH] =?UTF-8?q?custom=5Fcomponents/bahmcloud=5Fstore/panel/app?= =?UTF-8?q?.js=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bahmcloud_store/panel/app.js | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 custom_components/bahmcloud_store/panel/app.js diff --git a/custom_components/bahmcloud_store/panel/app.js b/custom_components/bahmcloud_store/panel/app.js new file mode 100644 index 0000000..f18ca5e --- /dev/null +++ b/custom_components/bahmcloud_store/panel/app.js @@ -0,0 +1,73 @@ +async function apiGet() { + const r = await fetch("/api/bahmcloud_store?op=list", { credentials: "same-origin" }); + return await r.json(); +} + +async function apiPost(payload) { + const r = await fetch("/api/bahmcloud_store", { + method: "POST", + headers: { "Content-Type": "application/json" }, + credentials: "same-origin", + body: JSON.stringify(payload), + }); + return await r.json(); +} + +function el(tag, attrs = {}, children = []) { + const n = document.createElement(tag); + Object.entries(attrs).forEach(([k, v]) => (k === "class" ? (n.className = v) : n.setAttribute(k, v))); + children.forEach((c) => n.appendChild(typeof c === "string" ? document.createTextNode(c) : c)); + return n; +} + +function render(data) { + const list = document.getElementById("list"); + const status = document.getElementById("status"); + list.innerHTML = ""; + + status.textContent = data.last_error ? `Error: ${data.last_error}` : `Store: ${data.store_url}`; + + data.packages.forEach((p) => { + const installedBadge = el("span", { class: "badge" }, [p.installed ? "Installed" : "Not installed"]); + const ver = el("div", { class: "muted" }, [ + `Installed: ${p.installed_version || "-"} | Latest: ${p.latest_version || "-"}` + ]); + + const btnInstall = el("button", {}, [p.installed ? "Reinstall" : "Install"]); + btnInstall.onclick = async () => { + btnInstall.disabled = true; + await apiPost({ op: "install", package_id: p.id }); + await load(); + }; + + const btnUpdate = el("button", {}, ["Update"]); + btnUpdate.disabled = !p.installed; + btnUpdate.onclick = async () => { + btnUpdate.disabled = true; + await apiPost({ op: "update", package_id: p.id }); + await load(); + }; + + const top = el("div", { class: "row" }, [ + el("div", {}, [el("strong", {}, [p.name]), el("span", { class: "muted" }, [" (" + p.id + ")"])]), + el("div", {}, [installedBadge]), + ]); + + const actions = el("div", { class: "row" }, [el("div", {}, [ver]), el("div", {}, [btnInstall, btnUpdate])]); + + list.appendChild(el("div", { class: "card" }, [top, actions])); + }); +} + +async function load() { + const data = await apiGet(); + render(data); +} + +document.getElementById("refresh").onclick = load; +document.getElementById("updateAll").onclick = async () => { + await apiPost({ op: "update_all" }); + await load(); +}; + +load();