Support ingress custom panels (#3085)

* Support ingress custom panels

* Fix types

* Add disabled placeholder to network card
This commit is contained in:
Paulus Schoutsen 2019-04-11 11:42:52 -07:00 committed by GitHub
parent 5dbd5c7395
commit bbae3291e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 24 deletions

View File

@ -44,6 +44,7 @@ class HassioAddonNetwork extends EventsMixin(PolymerElement) {
<td>[[item.container]]</td>
<td>
<paper-input
placeholder="disabled"
value="{{item.host}}"
no-label-float=""
></paper-input>

View File

@ -17,6 +17,9 @@ import {
HassioSupervisorInfo,
HassioHostInfo,
HassioHomeAssistantInfo,
fetchHassioAddonInfo,
createHassioSession,
HassioPanelInfo,
} from "../../src/data/hassio";
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
@ -32,6 +35,7 @@ customElements.get("paper-icon-button").prototype._keyBindings = {};
@customElement("hassio-main")
class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
@property() public hass!: HomeAssistant;
@property() public panel!: HassioPanelInfo;
protected routerOptions: RouterOptions = {
// Hass.io has a page with tabs, so we route all non-matching routes to it.
@ -117,6 +121,11 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
}
private async _fetchData() {
if (this.panel.config && this.panel.config.ingress) {
await this._redirectIngress(this.panel.config.ingress);
return;
}
const [supervisorInfo, hostInfo, hassInfo] = await Promise.all([
fetchHassioSupervisorInfo(this.hass),
fetchHassioHostInfo(this.hass),
@ -127,6 +136,28 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
this._hassInfo = hassInfo;
}
private async _redirectIngress(addonSlug: string) {
try {
const [addon] = await Promise.all([
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_url) {
throw new Error("Add-on does not support Ingress");
}
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);
} catch (err) {
alert(`Unable to open ingress connection `);
}
}
private _apiCalled(ev) {
if (!ev.detail.success) {
return;

View File

@ -15,7 +15,7 @@ import "./ha-icon";
import "../components/user/ha-user-badge";
import isComponentLoaded from "../common/config/is_component_loaded";
import { HomeAssistant, Panel } from "../types";
import { HomeAssistant, PanelInfo } from "../types";
import { fireEvent } from "../common/dom/fire_event";
import { DEFAULT_PANEL } from "../common/const";
@ -32,7 +32,9 @@ const computePanels = (hass: HomeAssistant) => {
logbook: 2,
history: 3,
};
const result: Panel[] = Object.values(panels).filter((panel) => panel.title);
const result: PanelInfo[] = Object.values(panels).filter(
(panel) => panel.title
);
result.sort((a, b) => {
const aBuiltIn = a.component_name in sortValue;

View File

@ -1,4 +1,11 @@
import { HomeAssistant } from "../types";
import { HomeAssistant, PanelInfo } from "../types";
export type HassioPanelInfo = PanelInfo<
| undefined
| {
ingress?: string;
}
>;
interface HassioResponse<T> {
data: T;

View File

@ -1,3 +1,5 @@
import { PanelInfo } from "../types";
export interface CustomPanelConfig {
name: string;
embed_iframe: boolean;
@ -6,3 +8,7 @@ export interface CustomPanelConfig {
module_url?: string;
html_url?: string;
}
export type CustomPanelInfo<T = {}> = PanelInfo<
T & { _panel_custom: CustomPanelConfig }
>;

View File

@ -4,8 +4,7 @@ import { createCustomPanelElement } from "../util/custom-panel/create-custom-pan
import { setCustomPanelProperties } from "../util/custom-panel/set-custom-panel-properties";
import { fireEvent } from "../common/dom/fire_event";
import { PolymerElement } from "@polymer/polymer";
import { Panel } from "../types";
import { CustomPanelConfig } from "../data/panel_custom";
import { CustomPanelInfo } from "../data/panel_custom";
declare global {
interface Window {
@ -39,12 +38,12 @@ function setProperties(properties) {
setCustomPanelProperties(panelEl, properties);
}
function initialize(panel: Panel, properties: {}) {
function initialize(panel: CustomPanelInfo, properties: {}) {
const style = document.createElement("style");
style.innerHTML = "body{margin:0}";
document.head.appendChild(style);
const config = panel.config!._panel_custom as CustomPanelConfig;
const config = panel.config._panel_custom;
let start: Promise<unknown> = Promise.resolve();
if (!webComponentsSupported) {

View File

@ -2,8 +2,8 @@ import { property, PropertyValues, UpdatingElement } from "lit-element";
import { loadCustomPanel } from "../../util/custom-panel/load-custom-panel";
import { createCustomPanelElement } from "../../util/custom-panel/create-custom-panel-element";
import { setCustomPanelProperties } from "../../util/custom-panel/set-custom-panel-properties";
import { HomeAssistant, Route, Panel } from "../../types";
import { CustomPanelConfig } from "../../data/panel_custom";
import { HomeAssistant, Route } from "../../types";
import { CustomPanelInfo } from "../../data/panel_custom";
import { navigate } from "../../common/navigate";
declare global {
@ -16,7 +16,7 @@ export class HaPanelCustom extends UpdatingElement {
@property() public hass!: HomeAssistant;
@property() public narrow!: boolean;
@property() public route!: Route;
@property() public panel!: Panel;
@property() public panel!: CustomPanelInfo;
private _setProperties?: (props: {}) => void | undefined;
// Since navigate fires events on `window`, we need to expose this as a function
@ -66,8 +66,8 @@ export class HaPanelCustom extends UpdatingElement {
}
}
private _createPanel(panel: Panel) {
const config = panel.config!._panel_custom as CustomPanelConfig;
private _createPanel(panel: CustomPanelInfo) {
const config = panel.config!._panel_custom;
const tempA = document.createElement("a");
tempA.href = config.html_url || config.js_url || config.module_url || "";

View File

@ -78,16 +78,16 @@ export interface Themes {
themes: { [key: string]: Theme };
}
export interface Panel {
export interface PanelInfo<T = {} | null> {
component_name: string;
config: { [key: string]: any } | null;
config: T;
icon: string | null;
title: string | null;
url_path: string;
}
export interface Panels {
[name: string]: Panel;
[name: string]: PanelInfo;
}
export interface Translation {
@ -212,14 +212,6 @@ export type CameraEntity = HassEntityBase & {
};
};
export interface PanelInfo<T = unknown> {
component_name: string;
icon?: string;
title?: string;
url_path: string;
config: T;
}
export interface Route {
prefix: string;
path: string;
@ -229,7 +221,7 @@ export interface PanelElement extends HTMLElement {
hass?: HomeAssistant;
narrow?: boolean;
route?: Route | null;
panel?: Panel;
panel?: PanelInfo;
}
export interface LocalizeMixin {