custom_components/bahmcloud_store/panel/panel.js aktualisiert
This commit is contained in:
@@ -40,6 +40,45 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Mobile navigation helpers ---
|
||||
|
||||
_toggleMenu() {
|
||||
// Preferred: HA listens to these events in many builds
|
||||
try {
|
||||
window.dispatchEvent(new CustomEvent("hass-toggle-menu", { bubbles: true, composed: true }));
|
||||
window.dispatchEvent(new CustomEvent("hass-toggle-drawer", { bubbles: true, composed: true }));
|
||||
} catch (_) {}
|
||||
|
||||
// Fallback: try to find the drawer and toggle it (best-effort)
|
||||
try {
|
||||
const ha = document.querySelector("home-assistant");
|
||||
const main = ha?.shadowRoot?.querySelector("home-assistant-main");
|
||||
const drawerLayout =
|
||||
main?.shadowRoot?.querySelector("app-drawer-layout") ||
|
||||
main?.shadowRoot?.querySelector("ha-drawer") ||
|
||||
main?.shadowRoot?.querySelector("ha-sidebar");
|
||||
|
||||
if (drawerLayout?.toggleDrawer) {
|
||||
drawerLayout.toggleDrawer();
|
||||
return;
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
// If nothing works, show a hint
|
||||
this._error = "Unable to open the sidebar on this client. Use the browser back button.";
|
||||
this._update();
|
||||
}
|
||||
|
||||
_goBack() {
|
||||
// Works even if HA chrome is hidden
|
||||
try {
|
||||
history.back();
|
||||
} catch (_) {
|
||||
// fallback
|
||||
window.location.href = "/";
|
||||
}
|
||||
}
|
||||
|
||||
async _addCustomRepo() {
|
||||
if (!this._hass) return;
|
||||
|
||||
@@ -93,13 +132,66 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
/* Do NOT force viewport height on mobile.
|
||||
Let Home Assistant handle layout (header/sidebar). */
|
||||
height: auto;
|
||||
min-height: 100%;
|
||||
--bcs-accent: #1E88E5; /* Bahmcloud Blue */
|
||||
}
|
||||
|
||||
/* Mobile-safe top bar that replaces HA chrome if HA renders this panel fullscreen */
|
||||
.mobilebar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
|
||||
background: var(--app-header-background-color, var(--card-background-color));
|
||||
color: var(--app-header-text-color, var(--primary-text-color));
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
|
||||
.mobilebar .left,
|
||||
.mobilebar .right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.iconbtn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--divider-color);
|
||||
background: color-mix(in srgb, var(--card-background-color) 80%, transparent);
|
||||
color: inherit;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
font-weight: 900;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.brandtitle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.brandtitle .t {
|
||||
font-size: 16px;
|
||||
font-weight: 900;
|
||||
}
|
||||
.brandtitle .s {
|
||||
font-size: 12px;
|
||||
color: var(--secondary-text-color);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
padding: 16px;
|
||||
max-width: 1100px;
|
||||
@@ -108,26 +200,6 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 13px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
@@ -151,12 +223,6 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--bcs-accent) 20%, transparent);
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 9px 12px;
|
||||
border-radius: 12px;
|
||||
@@ -244,18 +310,23 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
a:hover { text-decoration: underline; }
|
||||
</style>
|
||||
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<div>
|
||||
<div class="title">Bahmcloud Store</div>
|
||||
<div class="subtitle" id="subtitle">BCS — loading…</div>
|
||||
<!-- This bar ensures navigation on mobile even if HA renders fullscreen panels -->
|
||||
<div class="mobilebar">
|
||||
<div class="left">
|
||||
<div class="iconbtn" id="menuBtn" title="Menu">☰</div>
|
||||
<div class="iconbtn" id="backBtn" title="Back">←</div>
|
||||
<div class="brandtitle">
|
||||
<div class="t">Bahmcloud Store</div>
|
||||
<div class="s" id="subtitle">BCS — loading…</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div class="right">
|
||||
<button id="refreshBtn">Refresh</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wrap">
|
||||
<div class="tabs">
|
||||
<div class="tab" data-view="store">Store</div>
|
||||
<div class="tab" data-view="manage">Manage repositories</div>
|
||||
@@ -268,6 +339,8 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
`;
|
||||
|
||||
root.getElementById("refreshBtn").addEventListener("click", () => this._load());
|
||||
root.getElementById("menuBtn").addEventListener("click", () => this._toggleMenu());
|
||||
root.getElementById("backBtn").addEventListener("click", () => this._goBack());
|
||||
|
||||
for (const tab of root.querySelectorAll(".tab")) {
|
||||
tab.addEventListener("click", () => {
|
||||
@@ -281,8 +354,8 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
const root = this.shadowRoot;
|
||||
const content = root.getElementById("content");
|
||||
const err = root.getElementById("error");
|
||||
|
||||
const subtitle = root.getElementById("subtitle");
|
||||
|
||||
const v = this._data?.version ? String(this._data.version) : null;
|
||||
subtitle.textContent = v ? `BCS ${v}` : "BCS — loading…";
|
||||
|
||||
@@ -358,7 +431,7 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
<div><strong>${this._esc(r.name)}</strong></div>
|
||||
<div class="muted">${this._esc(r.url)}</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div>
|
||||
<button class="primary" data-remove="${this._esc(r.id)}">Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -382,7 +455,7 @@ class BahmcloudStorePanel extends HTMLElement {
|
||||
<input id="addName" placeholder="My Integration" value="${this._esc(this._customAddName)}" />
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<div>
|
||||
<button id="addBtn" class="primary">Add repository</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user