mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Show small header on ingress panels when the sidebar is hidden (#6488)
This commit is contained in:
parent
5400b1da96
commit
c17ebfd279
@ -31,6 +31,10 @@ class HassioMarkdownDialog extends LitElement {
|
|||||||
this._opened = true;
|
this._opened = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public closeDialog() {
|
||||||
|
this._opened = false;
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this._opened) {
|
if (!this._opened) {
|
||||||
return html``;
|
return html``;
|
||||||
@ -38,7 +42,7 @@ class HassioMarkdownDialog extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
open
|
open
|
||||||
@closing=${this._closeDialog}
|
@closed=${this.closeDialog}
|
||||||
.heading=${createCloseHeading(this.hass, this.title)}
|
.heading=${createCloseHeading(this.hass, this.title)}
|
||||||
>
|
>
|
||||||
<ha-markdown .content=${this.content || ""}></ha-markdown>
|
<ha-markdown .content=${this.content || ""}></ha-markdown>
|
||||||
@ -46,10 +50,6 @@ class HassioMarkdownDialog extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _closeDialog(): void {
|
|
||||||
this._opened = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [
|
return [
|
||||||
haStyleDialog,
|
haStyleDialog,
|
||||||
|
@ -1,93 +1,29 @@
|
|||||||
import { PolymerElement } from "@polymer/polymer";
|
|
||||||
import {
|
import {
|
||||||
customElement,
|
html,
|
||||||
property,
|
|
||||||
internalProperty,
|
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
|
customElement,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
import "./hassio-router";
|
||||||
|
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
|
||||||
|
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
|
||||||
|
import { HomeAssistant, Route } from "../../src/types";
|
||||||
|
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
|
||||||
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
|
||||||
import { fireEvent } from "../../src/common/dom/fire_event";
|
import { fireEvent } from "../../src/common/dom/fire_event";
|
||||||
import { navigate } from "../../src/common/navigate";
|
|
||||||
import { atLeastVersion } from "../../src/common/config/version";
|
|
||||||
import { fetchHassioAddonInfo } from "../../src/data/hassio/addon";
|
|
||||||
import {
|
|
||||||
fetchHassioHassOsInfo,
|
|
||||||
fetchHassioHostInfo,
|
|
||||||
HassioHassOSInfo,
|
|
||||||
HassioHostInfo,
|
|
||||||
} from "../../src/data/hassio/host";
|
|
||||||
import {
|
|
||||||
createHassioSession,
|
|
||||||
fetchHassioHomeAssistantInfo,
|
|
||||||
fetchHassioSupervisorInfo,
|
|
||||||
fetchHassioInfo,
|
|
||||||
HassioHomeAssistantInfo,
|
|
||||||
HassioInfo,
|
|
||||||
HassioPanelInfo,
|
|
||||||
HassioSupervisorInfo,
|
|
||||||
} from "../../src/data/hassio/supervisor";
|
|
||||||
import {
|
|
||||||
AlertDialogParams,
|
|
||||||
showAlertDialog,
|
|
||||||
} from "../../src/dialogs/generic/show-dialog-box";
|
|
||||||
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
||||||
import {
|
import { atLeastVersion } from "../../src/common/config/version";
|
||||||
HassRouterPage,
|
|
||||||
RouterOptions,
|
|
||||||
} from "../../src/layouts/hass-router-page";
|
|
||||||
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
|
|
||||||
import "../../src/resources/ha-style";
|
|
||||||
import { HomeAssistant } from "../../src/types";
|
|
||||||
// Don't codesplit it, that way the dashboard always loads fast.
|
|
||||||
import "./hassio-panel";
|
|
||||||
|
|
||||||
@customElement("hassio-main")
|
@customElement("hassio-main")
|
||||||
class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
|
export class HassioMain extends urlSyncMixin(ProvideHassLitMixin(LitElement)) {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public panel!: HassioPanelInfo;
|
@property() public panel!: HassioPanelInfo;
|
||||||
|
|
||||||
@property() public narrow!: boolean;
|
@property() public narrow!: boolean;
|
||||||
|
|
||||||
protected routerOptions: RouterOptions = {
|
@property() public route?: Route;
|
||||||
// Hass.io has a page with tabs, so we route all non-matching routes to it.
|
|
||||||
defaultPage: "dashboard",
|
|
||||||
initialLoad: () => this._fetchData(),
|
|
||||||
showLoading: true,
|
|
||||||
routes: {
|
|
||||||
dashboard: {
|
|
||||||
tag: "hassio-panel",
|
|
||||||
cache: true,
|
|
||||||
},
|
|
||||||
snapshots: "dashboard",
|
|
||||||
store: "dashboard",
|
|
||||||
system: "dashboard",
|
|
||||||
addon: {
|
|
||||||
tag: "hassio-addon-dashboard",
|
|
||||||
load: () =>
|
|
||||||
import(
|
|
||||||
/* webpackChunkName: "hassio-addon-dashboard" */ "./addon-view/hassio-addon-dashboard"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
ingress: {
|
|
||||||
tag: "hassio-ingress-view",
|
|
||||||
load: () =>
|
|
||||||
import(
|
|
||||||
/* webpackChunkName: "hassio-ingress-view" */ "./ingress-view/hassio-ingress-view"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
@internalProperty() private _supervisorInfo: HassioSupervisorInfo;
|
|
||||||
|
|
||||||
@internalProperty() private _hostInfo: HassioHostInfo;
|
|
||||||
|
|
||||||
@internalProperty() private _hassioInfo?: HassioInfo;
|
|
||||||
|
|
||||||
@internalProperty() private _hassOsInfo?: HassioHassOSInfo;
|
|
||||||
|
|
||||||
@internalProperty() private _hassInfo: HassioHomeAssistantInfo;
|
|
||||||
|
|
||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
@ -102,20 +38,6 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
|
|||||||
this.hass.selectedTheme
|
this.hass.selectedTheme
|
||||||
);
|
);
|
||||||
|
|
||||||
this.style.setProperty(
|
|
||||||
"--app-header-background-color",
|
|
||||||
"var(--sidebar-background-color)"
|
|
||||||
);
|
|
||||||
this.style.setProperty(
|
|
||||||
"--app-header-text-color",
|
|
||||||
"var(--sidebar-text-color)"
|
|
||||||
);
|
|
||||||
this.style.setProperty(
|
|
||||||
"--app-header-border-bottom",
|
|
||||||
"1px solid var(--divider-color)"
|
|
||||||
);
|
|
||||||
|
|
||||||
this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev));
|
|
||||||
// Paulus - March 17, 2019
|
// Paulus - March 17, 2019
|
||||||
// We went to a single hass-toggle-menu event in HA 0.90. However, the
|
// We went to a single hass-toggle-menu event in HA 0.90. However, the
|
||||||
// supervisor UI can also run under older versions of Home Assistant.
|
// supervisor UI can also run under older versions of Home Assistant.
|
||||||
@ -148,152 +70,18 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
makeDialogManager(this, document.body);
|
makeDialogManager(this, this.shadowRoot!);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updatePageEl(el) {
|
protected render() {
|
||||||
// the tabs page does its own routing so needs full route.
|
return html`
|
||||||
const route = el.nodeName === "HASSIO-PANEL" ? this.route : this.routeTail;
|
<hassio-router
|
||||||
|
.hass=${this.hass}
|
||||||
if ("setProperties" in el) {
|
.route=${this.route}
|
||||||
// As long as we have Polymer pages
|
.panel=${this.panel}
|
||||||
(el as PolymerElement).setProperties({
|
.narrow=${this.narrow}
|
||||||
hass: this.hass,
|
></hassio-router>
|
||||||
narrow: this.narrow,
|
`;
|
||||||
supervisorInfo: this._supervisorInfo,
|
|
||||||
hassioInfo: this._hassioInfo,
|
|
||||||
hostInfo: this._hostInfo,
|
|
||||||
hassInfo: this._hassInfo,
|
|
||||||
hassOsInfo: this._hassOsInfo,
|
|
||||||
route,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
el.hass = this.hass;
|
|
||||||
el.narrow = this.narrow;
|
|
||||||
el.supervisorInfo = this._supervisorInfo;
|
|
||||||
el.hassioInfo = this._hassioInfo;
|
|
||||||
el.hostInfo = this._hostInfo;
|
|
||||||
el.hassInfo = this._hassInfo;
|
|
||||||
el.hassOsInfo = this._hassOsInfo;
|
|
||||||
el.route = route;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _fetchData() {
|
|
||||||
if (this.panel.config && this.panel.config.ingress) {
|
|
||||||
await this._redirectIngress(this.panel.config.ingress);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [supervisorInfo, hostInfo, hassInfo, hassioInfo] = await Promise.all([
|
|
||||||
fetchHassioSupervisorInfo(this.hass),
|
|
||||||
fetchHassioHostInfo(this.hass),
|
|
||||||
fetchHassioHomeAssistantInfo(this.hass),
|
|
||||||
fetchHassioInfo(this.hass),
|
|
||||||
]);
|
|
||||||
this._supervisorInfo = supervisorInfo;
|
|
||||||
this._hassioInfo = hassioInfo;
|
|
||||||
this._hostInfo = hostInfo;
|
|
||||||
this._hassInfo = hassInfo;
|
|
||||||
|
|
||||||
if (this._hostInfo.features && this._hostInfo.features.includes("hassos")) {
|
|
||||||
this._hassOsInfo = await fetchHassioHassOsInfo(this.hass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _redirectIngress(addonSlug: string) {
|
|
||||||
// When we trigger a navigation, we sleep to make sure we don't
|
|
||||||
// show the hassio dashboard before navigating away.
|
|
||||||
const awaitAlert = async (
|
|
||||||
alertParams: AlertDialogParams,
|
|
||||||
action: () => void
|
|
||||||
) => {
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
alertParams.confirm = resolve;
|
|
||||||
showAlertDialog(this, alertParams);
|
|
||||||
});
|
|
||||||
action();
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
||||||
};
|
|
||||||
|
|
||||||
const createSessionPromise = createHassioSession(this.hass).then(
|
|
||||||
() => true,
|
|
||||||
() => false
|
|
||||||
);
|
|
||||||
|
|
||||||
let addon;
|
|
||||||
|
|
||||||
try {
|
|
||||||
addon = await fetchHassioAddonInfo(this.hass, addonSlug);
|
|
||||||
} catch (err) {
|
|
||||||
await awaitAlert(
|
|
||||||
{
|
|
||||||
text: "Unable to fetch add-on info to start Ingress",
|
|
||||||
title: "Supervisor",
|
|
||||||
},
|
|
||||||
() => history.back()
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!addon.ingress_url) {
|
|
||||||
await awaitAlert(
|
|
||||||
{
|
|
||||||
text: "Add-on does not support Ingress",
|
|
||||||
title: addon.name,
|
|
||||||
},
|
|
||||||
() => history.back()
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addon.state !== "started") {
|
|
||||||
await awaitAlert(
|
|
||||||
{
|
|
||||||
text: "Add-on is not running. Please start it first",
|
|
||||||
title: addon.name,
|
|
||||||
},
|
|
||||||
() => navigate(this, `/hassio/addon/${addon.slug}/info`, true)
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(await createSessionPromise)) {
|
|
||||||
await awaitAlert(
|
|
||||||
{
|
|
||||||
text: "Unable to create an Ingress session",
|
|
||||||
title: addon.name,
|
|
||||||
},
|
|
||||||
() => history.back()
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
location.assign(addon.ingress_url);
|
|
||||||
// await a promise that doesn't resolve, so we show the loading screen
|
|
||||||
// while we load the next page.
|
|
||||||
await new Promise(() => undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _apiCalled(ev) {
|
|
||||||
if (!ev.detail.success) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let tries = 1;
|
|
||||||
|
|
||||||
const tryUpdate = () => {
|
|
||||||
this._fetchData().catch(() => {
|
|
||||||
tries += 1;
|
|
||||||
setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
tryUpdate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import {
|
|||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { HassioHassOSInfo, HassioHostInfo } from "../../src/data/hassio/host";
|
import { HassioHassOSInfo, HassioHostInfo } from "../../src/data/hassio/host";
|
||||||
import {
|
import {
|
||||||
@ -33,6 +35,9 @@ class HassioPanel extends LitElement {
|
|||||||
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
|
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
if (!this.supervisorInfo) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
return html`
|
return html`
|
||||||
<hassio-panel-router
|
<hassio-panel-router
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
@ -46,6 +51,16 @@ class HassioPanel extends LitElement {
|
|||||||
></hassio-panel-router>
|
></hassio-panel-router>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return css`
|
||||||
|
:host {
|
||||||
|
--app-header-background-color: var(--sidebar-background-color);
|
||||||
|
--app-header-text-color: var(--sidebar-text-color);
|
||||||
|
--app-header-border-bottom: 1px solid var(--divider-color);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
150
hassio/src/hassio-router.ts
Normal file
150
hassio/src/hassio-router.ts
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
import {
|
||||||
|
customElement,
|
||||||
|
property,
|
||||||
|
internalProperty,
|
||||||
|
PropertyValues,
|
||||||
|
} from "lit-element";
|
||||||
|
import {
|
||||||
|
fetchHassioHassOsInfo,
|
||||||
|
fetchHassioHostInfo,
|
||||||
|
HassioHassOSInfo,
|
||||||
|
HassioHostInfo,
|
||||||
|
} from "../../src/data/hassio/host";
|
||||||
|
import {
|
||||||
|
fetchHassioHomeAssistantInfo,
|
||||||
|
fetchHassioSupervisorInfo,
|
||||||
|
fetchHassioInfo,
|
||||||
|
HassioHomeAssistantInfo,
|
||||||
|
HassioInfo,
|
||||||
|
HassioPanelInfo,
|
||||||
|
HassioSupervisorInfo,
|
||||||
|
} from "../../src/data/hassio/supervisor";
|
||||||
|
import {
|
||||||
|
HassRouterPage,
|
||||||
|
RouterOptions,
|
||||||
|
} from "../../src/layouts/hass-router-page";
|
||||||
|
import "../../src/resources/ha-style";
|
||||||
|
import { HomeAssistant } from "../../src/types";
|
||||||
|
// Don't codesplit it, that way the dashboard always loads fast.
|
||||||
|
import "./hassio-panel";
|
||||||
|
|
||||||
|
@customElement("hassio-router")
|
||||||
|
class HassioRouter extends HassRouterPage {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public panel!: HassioPanelInfo;
|
||||||
|
|
||||||
|
@property() public narrow!: boolean;
|
||||||
|
|
||||||
|
protected routerOptions: RouterOptions = {
|
||||||
|
// Hass.io has a page with tabs, so we route all non-matching routes to it.
|
||||||
|
defaultPage: "dashboard",
|
||||||
|
initialLoad: () => this._fetchData(),
|
||||||
|
showLoading: true,
|
||||||
|
routes: {
|
||||||
|
dashboard: {
|
||||||
|
tag: "hassio-panel",
|
||||||
|
cache: true,
|
||||||
|
},
|
||||||
|
snapshots: "dashboard",
|
||||||
|
store: "dashboard",
|
||||||
|
system: "dashboard",
|
||||||
|
addon: {
|
||||||
|
tag: "hassio-addon-dashboard",
|
||||||
|
load: () =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "hassio-addon-dashboard" */ "./addon-view/hassio-addon-dashboard"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
ingress: {
|
||||||
|
tag: "hassio-ingress-view",
|
||||||
|
load: () =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "hassio-ingress-view" */ "./ingress-view/hassio-ingress-view"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@internalProperty() private _supervisorInfo: HassioSupervisorInfo;
|
||||||
|
|
||||||
|
@internalProperty() private _hostInfo: HassioHostInfo;
|
||||||
|
|
||||||
|
@internalProperty() private _hassioInfo?: HassioInfo;
|
||||||
|
|
||||||
|
@internalProperty() private _hassOsInfo?: HassioHassOSInfo;
|
||||||
|
|
||||||
|
@internalProperty() private _hassInfo: HassioHomeAssistantInfo;
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
this.addEventListener("hass-api-called", (ev) => this._apiCalled(ev));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updatePageEl(el) {
|
||||||
|
// the tabs page does its own routing so needs full route.
|
||||||
|
const route = el.nodeName === "HASSIO-PANEL" ? this.route : this.routeTail;
|
||||||
|
|
||||||
|
el.hass = this.hass;
|
||||||
|
el.narrow = this.narrow;
|
||||||
|
el.supervisorInfo = this._supervisorInfo;
|
||||||
|
el.hassioInfo = this._hassioInfo;
|
||||||
|
el.hostInfo = this._hostInfo;
|
||||||
|
el.hassInfo = this._hassInfo;
|
||||||
|
el.hassOsInfo = this._hassOsInfo;
|
||||||
|
el.route = route;
|
||||||
|
|
||||||
|
if (el.localName === "hassio-ingress-view") {
|
||||||
|
el.ingressPanel = this.panel.config && this.panel.config.ingress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchData() {
|
||||||
|
if (this.panel.config && this.panel.config.ingress) {
|
||||||
|
this._redirectIngress(this.panel.config.ingress);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [supervisorInfo, hostInfo, hassInfo, hassioInfo] = await Promise.all([
|
||||||
|
fetchHassioSupervisorInfo(this.hass),
|
||||||
|
fetchHassioHostInfo(this.hass),
|
||||||
|
fetchHassioHomeAssistantInfo(this.hass),
|
||||||
|
fetchHassioInfo(this.hass),
|
||||||
|
]);
|
||||||
|
this._supervisorInfo = supervisorInfo;
|
||||||
|
this._hassioInfo = hassioInfo;
|
||||||
|
this._hostInfo = hostInfo;
|
||||||
|
this._hassInfo = hassInfo;
|
||||||
|
|
||||||
|
if (this._hostInfo.features && this._hostInfo.features.includes("hassos")) {
|
||||||
|
this._hassOsInfo = await fetchHassioHassOsInfo(this.hass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _redirectIngress(addonSlug: string) {
|
||||||
|
this.route = { prefix: "/hassio", path: `/ingress/${addonSlug}` };
|
||||||
|
}
|
||||||
|
|
||||||
|
private _apiCalled(ev) {
|
||||||
|
if (!ev.detail.success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tries = 1;
|
||||||
|
|
||||||
|
const tryUpdate = () => {
|
||||||
|
this._fetchData().catch(() => {
|
||||||
|
tries += 1;
|
||||||
|
setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
tryUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hassio-router": HassioRouter;
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,10 @@ import { createHassioSession } from "../../../src/data/hassio/supervisor";
|
|||||||
import "../../../src/layouts/hass-loading-screen";
|
import "../../../src/layouts/hass-loading-screen";
|
||||||
import "../../../src/layouts/hass-subpage";
|
import "../../../src/layouts/hass-subpage";
|
||||||
import { HomeAssistant, Route } from "../../../src/types";
|
import { HomeAssistant, Route } from "../../../src/types";
|
||||||
|
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
||||||
|
import { navigate } from "../../../src/common/navigate";
|
||||||
|
import { mdiMenu } from "@mdi/js";
|
||||||
|
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||||
|
|
||||||
@customElement("hassio-ingress-view")
|
@customElement("hassio-ingress-view")
|
||||||
class HassioIngressView extends LitElement {
|
class HassioIngressView extends LitElement {
|
||||||
@ -24,22 +28,45 @@ class HassioIngressView extends LitElement {
|
|||||||
|
|
||||||
@property() public route!: Route;
|
@property() public route!: Route;
|
||||||
|
|
||||||
|
@property() public ingressPanel = false;
|
||||||
|
|
||||||
@internalProperty() private _addon?: HassioAddonDetails;
|
@internalProperty() private _addon?: HassioAddonDetails;
|
||||||
|
|
||||||
|
@property({ type: Boolean })
|
||||||
|
public narrow = false;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this._addon) {
|
if (!this._addon) {
|
||||||
return html` <hass-loading-screen></hass-loading-screen> `;
|
return html` <hass-loading-screen></hass-loading-screen> `;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
const iframe = html`<iframe src=${this._addon.ingress_url!}></iframe>`;
|
||||||
<hass-subpage .header=${this._addon.name} hassio>
|
|
||||||
<iframe src=${this._addon.ingress_url}></iframe>
|
if (!this.ingressPanel) {
|
||||||
</hass-subpage>
|
return html`<hass-subpage
|
||||||
`;
|
.header=${this._addon.name}
|
||||||
|
.narrow=${this.narrow}
|
||||||
|
>
|
||||||
|
${iframe}
|
||||||
|
</hass-subpage>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`${this.narrow || this.hass.dockedSidebar === "always_hidden"
|
||||||
|
? html`<div class="header">
|
||||||
|
<mwc-icon-button
|
||||||
|
aria-label=${this.hass.localize("ui.sidebar.sidebar_toggle")}
|
||||||
|
@click=${this._toggleMenu}
|
||||||
|
>
|
||||||
|
<ha-svg-icon path=${mdiMenu}></ha-svg-icon>
|
||||||
|
</mwc-icon-button>
|
||||||
|
<div class="main-title">${this._addon.name}</div>
|
||||||
|
</div>
|
||||||
|
${iframe}`
|
||||||
|
: iframe}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.updated(changedProps);
|
||||||
|
|
||||||
if (!changedProps.has("route")) {
|
if (!changedProps.has("route")) {
|
||||||
return;
|
return;
|
||||||
@ -56,27 +83,56 @@ class HassioIngressView extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _fetchData(addonSlug: string) {
|
private async _fetchData(addonSlug: string) {
|
||||||
|
const createSessionPromise = createHassioSession(this.hass).then(
|
||||||
|
() => true,
|
||||||
|
() => false
|
||||||
|
);
|
||||||
|
|
||||||
|
let addon;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [addon] = await Promise.all([
|
addon = await fetchHassioAddonInfo(this.hass, addonSlug);
|
||||||
fetchHassioAddonInfo(this.hass, addonSlug).catch(() => {
|
|
||||||
throw new Error("Failed to fetch add-on info");
|
|
||||||
}),
|
|
||||||
createHassioSession(this.hass).catch(() => {
|
|
||||||
throw new Error("Failed to create an ingress session");
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!addon.ingress) {
|
|
||||||
throw new Error("This add-on does not support ingress");
|
|
||||||
}
|
|
||||||
|
|
||||||
this._addon = addon;
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
await showAlertDialog(this, {
|
||||||
console.error(err);
|
text: "Unable to fetch add-on info to start Ingress",
|
||||||
alert(err.message || "Unknown error starting ingress.");
|
title: "Supervisor",
|
||||||
|
});
|
||||||
history.back();
|
history.back();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!addon.ingress_url) {
|
||||||
|
await showAlertDialog(this, {
|
||||||
|
text: "Add-on does not support Ingress",
|
||||||
|
title: addon.name,
|
||||||
|
});
|
||||||
|
history.back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addon.state !== "started") {
|
||||||
|
await showAlertDialog(this, {
|
||||||
|
text: "Add-on is not running. Please start it first",
|
||||||
|
title: addon.name,
|
||||||
|
});
|
||||||
|
navigate(this, `/hassio/addon/${addon.slug}/info`, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(await createSessionPromise)) {
|
||||||
|
await showAlertDialog(this, {
|
||||||
|
text: "Unable to create an Ingress session",
|
||||||
|
title: addon.name,
|
||||||
|
});
|
||||||
|
history.back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._addon = addon;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _toggleMenu(): void {
|
||||||
|
fireEvent(this, "hass-toggle-menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
@ -87,6 +143,41 @@ class HassioIngressView extends LitElement {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header + iframe {
|
||||||
|
height: calc(100% - 40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 16px;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 16px;
|
||||||
|
pointer-events: none;
|
||||||
|
background-color: var(--app-header-background-color);
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--app-header-text-color, white);
|
||||||
|
border-bottom: var(--app-header-border-bottom, none);
|
||||||
|
box-sizing: border-box;
|
||||||
|
--mdc-icon-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-title {
|
||||||
|
margin: 0 0 0 24px;
|
||||||
|
line-height: 20px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mwc-icon-button {
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
hass-subpage {
|
||||||
|
--app-header-background-color: var(--sidebar-background-color);
|
||||||
|
--app-header-text-color: var(--sidebar-text-color);
|
||||||
|
--app-header-border-bottom: 1px solid var(--divider-color);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,15 @@ import {
|
|||||||
DialogClosedParams,
|
DialogClosedParams,
|
||||||
} from "../dialogs/make-dialog-manager";
|
} from "../dialogs/make-dialog-manager";
|
||||||
import { Constructor } from "../types";
|
import { Constructor } from "../types";
|
||||||
import { HassBaseEl } from "./hass-base-mixin";
|
|
||||||
import { HASSDomEvent } from "../common/dom/fire_event";
|
import { HASSDomEvent } from "../common/dom/fire_event";
|
||||||
|
import { UpdatingElement } from "lit-element";
|
||||||
|
import { ProvideHassElement } from "../mixins/provide-hass-lit-mixin";
|
||||||
|
|
||||||
const DEBUG = false;
|
const DEBUG = false;
|
||||||
|
|
||||||
export const urlSyncMixin = <T extends Constructor<HassBaseEl>>(
|
export const urlSyncMixin = <
|
||||||
|
T extends Constructor<UpdatingElement & ProvideHassElement>
|
||||||
|
>(
|
||||||
superClass: T
|
superClass: T
|
||||||
) =>
|
) =>
|
||||||
// Disable this functionality in the demo.
|
// Disable this functionality in the demo.
|
||||||
@ -35,11 +38,17 @@ export const urlSyncMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
private _dialogClosedListener = (
|
private _dialogClosedListener = (
|
||||||
ev: HASSDomEvent<DialogClosedParams>
|
ev: HASSDomEvent<DialogClosedParams>
|
||||||
) => {
|
) => {
|
||||||
|
if (DEBUG) {
|
||||||
|
console.log("dialog closed", ev.detail.dialog);
|
||||||
|
}
|
||||||
// If not closed by navigating back, and not a new dialog is open, remove the open state from history
|
// If not closed by navigating back, and not a new dialog is open, remove the open state from history
|
||||||
if (
|
if (
|
||||||
history.state?.open &&
|
history.state?.open &&
|
||||||
history.state?.dialog === ev.detail.dialog
|
history.state?.dialog === ev.detail.dialog
|
||||||
) {
|
) {
|
||||||
|
if (DEBUG) {
|
||||||
|
console.log("remove state", ev.detail.dialog);
|
||||||
|
}
|
||||||
this._ignoreNextPopState = true;
|
this._ignoreNextPopState = true;
|
||||||
history.back();
|
history.back();
|
||||||
}
|
}
|
||||||
@ -65,6 +74,9 @@ export const urlSyncMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
if (!state.open) {
|
if (!state.open) {
|
||||||
const closed = await closeDialog(state.dialog);
|
const closed = await closeDialog(state.dialog);
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
|
if (DEBUG) {
|
||||||
|
console.log("dialog could not be closed");
|
||||||
|
}
|
||||||
// dialog could not be closed, push state again
|
// dialog could not be closed, push state again
|
||||||
history.pushState(
|
history.pushState(
|
||||||
{
|
{
|
||||||
@ -78,6 +90,9 @@ export const urlSyncMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (state.oldState) {
|
if (state.oldState) {
|
||||||
|
if (DEBUG) {
|
||||||
|
console.log("handle old state");
|
||||||
|
}
|
||||||
this._handleDialogStateChange(state.oldState);
|
this._handleDialogStateChange(state.oldState);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user