custom_components/bahmcloud_store/panel/panel.js aktualisiert

This commit is contained in:
2026-01-15 17:41:58 +00:00
parent 745979b9a6
commit 19df0eea22

View File

@@ -24,6 +24,10 @@ class BahmcloudStorePanel extends HTMLElement {
this._readmeText = null; this._readmeText = null;
this._readmeHtml = null; this._readmeHtml = null;
this._readmeError = null; this._readmeError = null;
// Manual refresh UX state
this._refreshing = false;
this._status = ""; // short status line shown in UI
} }
set hass(hass) { set hass(hass) {
@@ -53,6 +57,34 @@ class BahmcloudStorePanel extends HTMLElement {
} }
} }
async _refreshAll() {
if (!this._hass) return;
if (this._refreshing) return;
this._refreshing = true;
this._error = null;
this._status = "Refreshing…";
this._update();
try {
// This triggers: POST /api/bcs?action=refresh
const resp = await this._hass.callApi("post", "bcs?action=refresh", {});
if (!resp?.ok) {
this._status = "";
this._error = this._safeText(resp?.message) || "Refresh failed.";
} else {
this._status = "Refresh done.";
}
} catch (e) {
this._status = "";
this._error = e?.message ? String(e.message) : String(e);
} finally {
this._refreshing = false;
// Always reload data after refresh attempt
await this._load();
}
}
_isDesktop() { _isDesktop() {
return window.matchMedia && window.matchMedia("(min-width: 1024px)").matches; return window.matchMedia && window.matchMedia("(min-width: 1024px)").matches;
} }
@@ -238,6 +270,16 @@ class BahmcloudStorePanel extends HTMLElement {
button:active{ transform: translateY(0px); box-shadow:none; } button:active{ transform: translateY(0px); box-shadow:none; }
button:disabled{ opacity: 0.55; cursor: not-allowed; } button:disabled{ opacity: 0.55; cursor: not-allowed; }
.statusline{
margin-left: 10px;
font-size: 12px;
color: var(--secondary-text-color);
max-width: 280px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.card{ .card{
border:1px solid var(--divider-color); border:1px solid var(--divider-color);
background:var(--card-background-color); background:var(--card-background-color);
@@ -363,6 +405,7 @@ class BahmcloudStorePanel extends HTMLElement {
</div> </div>
<div class="right"> <div class="right">
<button id="refreshBtn" class="primary">Refresh</button> <button id="refreshBtn" class="primary">Refresh</button>
<div class="statusline" id="statusLine"></div>
</div> </div>
</div> </div>
@@ -380,7 +423,8 @@ class BahmcloudStorePanel extends HTMLElement {
<div id="fabs"></div> <div id="fabs"></div>
`; `;
root.getElementById("refreshBtn").addEventListener("click", () => this._load()); // IMPORTANT: Refresh must trigger backend refresh, not only GET /api/bcs
root.getElementById("refreshBtn").addEventListener("click", () => this._refreshAll());
root.getElementById("menuBtn").addEventListener("click", () => this._toggleMenu()); root.getElementById("menuBtn").addEventListener("click", () => this._toggleMenu());
root.getElementById("backBtn").addEventListener("click", () => this._goBack()); root.getElementById("backBtn").addEventListener("click", () => this._goBack());
@@ -447,6 +491,15 @@ class BahmcloudStorePanel extends HTMLElement {
const err = root.getElementById("error"); const err = root.getElementById("error");
const subtitle = root.getElementById("subtitle"); const subtitle = root.getElementById("subtitle");
const fabs = root.getElementById("fabs"); const fabs = root.getElementById("fabs");
const statusLine = root.getElementById("statusLine");
const refreshBtn = root.getElementById("refreshBtn");
if (statusLine) statusLine.textContent = this._status || "";
if (refreshBtn) {
refreshBtn.disabled = !!this._refreshing;
refreshBtn.textContent = this._refreshing ? "Refreshing…" : "Refresh";
}
const v = this._safeText(this._data?.version); const v = this._safeText(this._data?.version);
subtitle.textContent = v ? `BCS ${v}` : "BCS — loading…"; subtitle.textContent = v ? `BCS ${v}` : "BCS — loading…";
@@ -497,6 +550,7 @@ class BahmcloudStorePanel extends HTMLElement {
this._restoreFocusState(focusState); this._restoreFocusState(focusState);
} }
// ---------- everything below is unchanged from your current file ----------
_renderStore() { _renderStore() {
const repos = Array.isArray(this._data.repos) ? this._data.repos : []; const repos = Array.isArray(this._data.repos) ? this._data.repos : [];
const categories = this._computeCategories(repos); const categories = this._computeCategories(repos);
@@ -758,7 +812,6 @@ class BahmcloudStorePanel extends HTMLElement {
if (!mount) return; if (!mount) return;
if (this._readmeText) { if (this._readmeText) {
// Client renderer may be unavailable; prefer server-provided HTML
if (this._readmeHtml) { if (this._readmeHtml) {
mount.innerHTML = this._readmeHtml; mount.innerHTML = this._readmeHtml;
this._postprocessRenderedMarkdown(mount); this._postprocessRenderedMarkdown(mount);
@@ -920,7 +973,7 @@ class BahmcloudStorePanel extends HTMLElement {
const t = typeof v; const t = typeof v;
if (t === "string") return v; if (t === "string") return v;
if (t === "number" || t === "boolean") return String(v); if (t === "number" || t === "boolean") return String(v);
return ""; // objects/arrays/functions => empty (prevents [object Object]) return "";
} }
_safeLower(v) { _safeLower(v) {