Add release notes and project prompts

This commit is contained in:
2026-03-23 14:09:29 +01:00
parent a8ff892993
commit b7d4d0ded4
11 changed files with 431 additions and 6 deletions

View File

@@ -56,6 +56,10 @@ class BahmcloudStorePanel extends HTMLElement {
this._versionsCache = {}; // repo_id -> [{ref,label,source}, ...]
this._versionsLoadingRepoId = null;
this._selectedVersionByRepoId = {}; // repo_id -> ref ("" means latest)
this._releaseNotesLoading = false;
this._releaseNotesText = null;
this._releaseNotesHtml = null;
this._releaseNotesError = null;
// History handling (mobile back button should go back to list, not exit panel)
this._historyBound = false;
@@ -442,6 +446,10 @@ class BahmcloudStorePanel extends HTMLElement {
this._readmeError = null;
this._readmeExpanded = false;
this._readmeCanToggle = false;
this._releaseNotesLoading = false;
this._releaseNotesText = null;
this._releaseNotesHtml = null;
this._releaseNotesError = null;
// Versions dropdown
if (!(repoId in this._selectedVersionByRepoId)) {
@@ -452,6 +460,7 @@ class BahmcloudStorePanel extends HTMLElement {
this._loadRepoDetails(repoId);
this._loadReadme(repoId);
this._loadVersions(repoId);
this._loadReleaseNotes(repoId);
}
@@ -499,6 +508,41 @@ class BahmcloudStorePanel extends HTMLElement {
}
}
async _loadReleaseNotes(repoId) {
if (!this._hass || !repoId) return;
this._releaseNotesLoading = true;
this._releaseNotesText = null;
this._releaseNotesHtml = null;
this._releaseNotesError = null;
this._update();
try {
const sel = this._safeText(this._selectedVersionByRepoId?.[repoId] || "").trim();
const qv = sel ? `&ref=${encodeURIComponent(sel)}` : "";
const resp = await this._hass.callApi(
"get",
`bcs/release_notes?repo_id=${encodeURIComponent(repoId)}${qv}`,
);
if (resp?.ok && typeof resp.release_notes === "string" && resp.release_notes.trim()) {
this._releaseNotesText = resp.release_notes;
this._releaseNotesHtml =
typeof resp.html === "string" && resp.html.trim() ? resp.html : null;
} else {
this._releaseNotesError =
this._safeText(resp?.message) || "Release notes not available for this version.";
}
} catch (e) {
this._releaseNotesError = e?.message
? String(e.message)
: "Release notes not available for this version.";
} finally {
this._releaseNotesLoading = false;
this._update();
}
}
async _loadReadme(repoId) {
if (!this._hass) return;
this._readmeLoading = true;
@@ -1250,6 +1294,31 @@ class BahmcloudStorePanel extends HTMLElement {
</div>
`;
const releaseNotesBlock = this._releaseNotesLoading
? `<div class="card" style="margin-top:12px;">Loading release notes...</div>`
: this._releaseNotesText
? `
<div class="card" style="margin-top:12px;">
<div class="row" style="align-items:center;">
<div><strong>Release Notes</strong></div>
<div class="muted small">${this._esc(selectedRef || latestVersion || "-")}</div>
</div>
<div id="releaseNotesPretty" class="md" style="margin-top:12px;"></div>
<details>
<summary>Show raw release notes</summary>
<div style="margin-top:10px;">
<pre class="readme">${this._esc(this._releaseNotesText)}</pre>
</div>
</details>
</div>
`
: `
<div class="card" style="margin-top:12px;">
<div><strong>Release Notes</strong></div>
<div class="muted" style="margin-top:8px;">${this._esc(this._releaseNotesError || "Release notes not available for this version.")}</div>
</div>
`;
const installBtn = `<button class="primary" id="btnInstall" ${installed || busy ? "disabled" : ""}>${busyInstall ? "Installing…" : installed ? "Installed" : "Install"}</button>`;
const updateBtn = `<button class="primary" id="btnUpdate" ${!updateAvailable || busy ? "disabled" : ""}>${busyUpdate ? "Updating…" : updateAvailable ? "Update" : "Up to date"}</button>`;
const uninstallBtn = `<button class="primary" id="btnUninstall" ${!installed || busy ? "disabled" : ""}>${busyUninstall ? "Uninstalling…" : "Uninstall"}</button>`;
@@ -1303,6 +1372,7 @@ class BahmcloudStorePanel extends HTMLElement {
</div>
${versionSelect}
${releaseNotesBlock}
<div class="row" style="margin-top:14px; gap:10px; flex-wrap:wrap;">
${installBtn}
@@ -1342,6 +1412,7 @@ class BahmcloudStorePanel extends HTMLElement {
if (!this._detailRepoId) return;
const v = selVersion.value != null ? String(selVersion.value) : "";
this._selectedVersionByRepoId[this._detailRepoId] = v;
this._loadReleaseNotes(this._detailRepoId);
});
}
@@ -1380,7 +1451,22 @@ class BahmcloudStorePanel extends HTMLElement {
}
const mount = root.getElementById("readmePretty");
if (!mount) return;
if (!mount) {
const releaseMount = root.getElementById("releaseNotesPretty");
if (releaseMount) {
if (this._releaseNotesText) {
if (this._releaseNotesHtml) {
releaseMount.innerHTML = this._releaseNotesHtml;
this._postprocessRenderedMarkdown(releaseMount);
} else {
releaseMount.innerHTML = `<div class="muted">Rendered HTML not available. Use "Show raw release notes".</div>`;
}
} else {
releaseMount.innerHTML = "";
}
}
return;
}
if (this._readmeText) {
if (this._readmeHtml) {
@@ -1392,6 +1478,20 @@ class BahmcloudStorePanel extends HTMLElement {
} else {
mount.innerHTML = "";
}
const releaseMount = root.getElementById("releaseNotesPretty");
if (releaseMount) {
if (this._releaseNotesText) {
if (this._releaseNotesHtml) {
releaseMount.innerHTML = this._releaseNotesHtml;
this._postprocessRenderedMarkdown(releaseMount);
} else {
releaseMount.innerHTML = `<div class="muted">Rendered HTML not available. Use "Show raw release notes".</div>`;
}
} else {
releaseMount.innerHTML = "";
}
}
}
_wireRestoreModal() {
@@ -1554,4 +1654,4 @@ class BahmcloudStorePanel extends HTMLElement {
}
}
customElements.define("bahmcloud-store-panel", BahmcloudStorePanel);
customElements.define("bahmcloud-store-panel", BahmcloudStorePanel);