diff --git a/src/pluginbattery/static/app.js b/src/pluginbattery/static/app.js index 244b755..12aceb4 100644 --- a/src/pluginbattery/static/app.js +++ b/src/pluginbattery/static/app.js @@ -106,17 +106,10 @@ function renderTable(rows) { tbody.replaceChildren(); rows.forEach((r, i) => { const tr = el("tr"); + if (r.category) tr.dataset.category = r.category; + if (r.url) tr.dataset.url = r.url; // kept for the modal header, not the row link tr.append(td(String(i + 1))); - - // Title cell — anchor with safe text. - const tdTitle = el("td"); - if (r.url) { - const a = el("a", { href: r.url, target: "_blank", rel: "noopener", text: r.title }); - tdTitle.appendChild(a); - } else { - tdTitle.textContent = r.title; - } - tr.appendChild(tdTitle); + tr.append(td(r.title)); const tenYrCls = r.ten_year_profit_eur < 0 ? "neg" : "pos"; tr.append( @@ -215,11 +208,10 @@ function captureInitialFromDOM() { const rows = Array.from(tbody.querySelectorAll("tr")); lastBatteries = rows.map((tr) => { const cells = tr.children; - const link = cells[1].querySelector("a"); return { category: tr.dataset.category || null, - title: (link ? link.textContent : cells[1].textContent).trim(), - url: link ? link.href : "", + title: cells[1].textContent.trim(), + url: tr.dataset.url || "", capacity_kwh: parseFloat(cells[2].textContent), power_kw: parseFloat(cells[3].textContent), price_eur: parseFloat(cells[4].textContent.replace("€", "")), @@ -274,7 +266,19 @@ let charts = { irr: null, soc: null, grid: null }; function openModalForBattery(row) { activeBattery = row; - tlTitle.textContent = `${row.title} — ${fmtNum(row.capacity_kwh)} kWh / ${fmtNum(row.power_kw, 1)} kW`; + tlTitle.replaceChildren(); + tlTitle.appendChild(document.createTextNode( + `${row.title} — ${fmtNum(row.capacity_kwh)} kWh / ${fmtNum(row.power_kw, 1)} kW`, + )); + if (row.url) { + const a = document.createElement("a"); + a.href = row.url; + a.target = "_blank"; + a.rel = "noopener"; + a.textContent = "view on store ↗"; + a.className = "shop-link"; + tlTitle.appendChild(a); + } if (!tlDate.value) tlDate.value = "2025-06-15"; modal.hidden = false; refreshTimeline(); @@ -423,8 +427,6 @@ function drawChart(key, axes, xs, ys, containerId, opts = {}) { // Hook up battery row clicks. tbody.addEventListener("click", (e) => { - // Ignore link clicks — let those go to the shop page if user explicitly wants it. - if (e.target.closest("a")) return; const tr = e.target.closest("tr"); if (!tr) return; const idx = Array.from(tbody.children).indexOf(tr); diff --git a/src/pluginbattery/static/style.css b/src/pluginbattery/static/style.css index 8162794..0999ad2 100644 --- a/src/pluginbattery/static/style.css +++ b/src/pluginbattery/static/style.css @@ -218,6 +218,8 @@ table#leaderboard tbody tr a { color: inherit; text-decoration: underline dotted .modal-card header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.75rem; } .modal-card h2 { margin: 0; font-size: 1.1rem; } +.modal-card h2 .shop-link { font-size: 0.75rem; font-weight: 400; margin-left: 0.75rem; color: var(--muted); } +.modal-card h2 .shop-link:hover { color: var(--link); } .modal-close { background: none; border: 0; font-size: 1.6rem; line-height: 1; color: var(--muted); cursor: pointer; padding: 0 0.5rem; } .modal-close:hover { color: var(--text); } diff --git a/src/pluginbattery/templates/index.html b/src/pluginbattery/templates/index.html index f68455c..fdfad24 100644 --- a/src/pluginbattery/templates/index.html +++ b/src/pluginbattery/templates/index.html @@ -5,7 +5,7 @@ Honest battery payback — vs thuisbatterijgids.nl - + @@ -114,9 +114,9 @@ {# rendered cells start below; legend follows the table. #} {% for r in initial.batteries %} - + {{ loop.index }} - {{ r.title }} + {{ r.title }} {{ '%.2f' % r.capacity_kwh }} {{ '%.1f' % r.power_kw }} €{{ '%.0f' % r.price_eur }} @@ -157,7 +157,7 @@ - +