mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 11:46:42 +00:00
Convert cloud dashboard to use Lit router (#3223)
This commit is contained in:
parent
e595637a10
commit
b2b18cb814
@ -34,6 +34,9 @@ export interface RouterOptions {
|
||||
showLoading?: boolean;
|
||||
// Promise that resolves when the initial data is loaded which is needed to show any route.
|
||||
initialLoad?: () => Promise<unknown>;
|
||||
// Hook that is called before rendering a new route. Allowing redirects.
|
||||
// If string returned, that page will be rendered instead.
|
||||
beforeRender?: (page: string) => string | undefined;
|
||||
routes: {
|
||||
// If it's a string, it is another route whose options should be adopted.
|
||||
[route: string]: RouteOptions | string;
|
||||
@ -48,7 +51,7 @@ export class HassRouterPage extends UpdatingElement {
|
||||
|
||||
protected routerOptions!: RouterOptions;
|
||||
|
||||
private _currentPage = "";
|
||||
protected _currentPage = "";
|
||||
private _currentLoadProm?: Promise<void>;
|
||||
private _cache = {};
|
||||
private _initialLoadDone = false;
|
||||
@ -101,6 +104,25 @@ export class HassRouterPage extends UpdatingElement {
|
||||
routeOptions = routerOptions.routes[newPage];
|
||||
}
|
||||
|
||||
if (routerOptions.beforeRender) {
|
||||
const result = routerOptions.beforeRender(newPage);
|
||||
if (result !== undefined) {
|
||||
newPage = result;
|
||||
routeOptions = routerOptions.routes[newPage];
|
||||
|
||||
// Handle redirects
|
||||
while (typeof routeOptions === "string") {
|
||||
newPage = routeOptions;
|
||||
routeOptions = routerOptions.routes[newPage];
|
||||
}
|
||||
|
||||
// Update the url if we know where we're mounted.
|
||||
if (route) {
|
||||
navigate(this, `${route.prefix}/${result}`, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this._currentPage === newPage) {
|
||||
if (this.lastChild) {
|
||||
this.updatePageEl(this.lastChild, changedProps);
|
||||
@ -245,6 +267,10 @@ export class HassRouterPage extends UpdatingElement {
|
||||
return this.updateComplete.then(() => this._currentLoadProm);
|
||||
}
|
||||
|
||||
protected createElement(tag: string) {
|
||||
return document.createElement(tag);
|
||||
}
|
||||
|
||||
protected updatePageEl(_pageEl, _changedProps?: PropertyValues) {
|
||||
// default we do nothing
|
||||
}
|
||||
@ -262,8 +288,7 @@ export class HassRouterPage extends UpdatingElement {
|
||||
this.removeChild(this.lastChild);
|
||||
}
|
||||
|
||||
const panelEl =
|
||||
this._cache[page] || document.createElement(routeOptions.tag);
|
||||
const panelEl = this._cache[page] || this.createElement(routeOptions.tag);
|
||||
this.updatePageEl(panelEl);
|
||||
this.appendChild(panelEl);
|
||||
|
||||
|
@ -1,145 +0,0 @@
|
||||
import "@polymer/app-route/app-route";
|
||||
import { timeOut } from "@polymer/polymer/lib/utils/async";
|
||||
import { Debouncer } from "@polymer/polymer/lib/utils/debounce";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
import "../ha-config-section";
|
||||
import "./ha-config-cloud-account";
|
||||
import "./ha-config-cloud-forgot-password";
|
||||
import "./ha-config-cloud-login";
|
||||
import "./ha-config-cloud-register";
|
||||
import NavigateMixin from "../../../mixins/navigate-mixin";
|
||||
|
||||
const LOGGED_IN_URLS = ["/account"];
|
||||
const NOT_LOGGED_IN_URLS = ["/login", "/register", "/forgot-password"];
|
||||
|
||||
/*
|
||||
* @appliesMixin NavigateMixin
|
||||
*/
|
||||
class HaConfigCloud extends NavigateMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<app-route
|
||||
route="[[route]]"
|
||||
pattern="/:page"
|
||||
data="{{_routeData}}"
|
||||
tail="{{_routeTail}}"
|
||||
></app-route>
|
||||
|
||||
<template
|
||||
is="dom-if"
|
||||
if='[[_equals(_routeData.page, "account")]]'
|
||||
restamp=""
|
||||
>
|
||||
<ha-config-cloud-account
|
||||
hass="[[hass]]"
|
||||
cloud-status="[[cloudStatus]]"
|
||||
is-wide="[[isWide]]"
|
||||
></ha-config-cloud-account>
|
||||
</template>
|
||||
|
||||
<template
|
||||
is="dom-if"
|
||||
if='[[_equals(_routeData.page, "login")]]'
|
||||
restamp=""
|
||||
>
|
||||
<ha-config-cloud-login
|
||||
page-name="login"
|
||||
hass="[[hass]]"
|
||||
is-wide="[[isWide]]"
|
||||
email="{{_loginEmail}}"
|
||||
flash-message="{{_flashMessage}}"
|
||||
></ha-config-cloud-login>
|
||||
</template>
|
||||
|
||||
<template
|
||||
is="dom-if"
|
||||
if='[[_equals(_routeData.page, "register")]]'
|
||||
restamp=""
|
||||
>
|
||||
<ha-config-cloud-register
|
||||
page-name="register"
|
||||
hass="[[hass]]"
|
||||
is-wide="[[isWide]]"
|
||||
email="{{_loginEmail}}"
|
||||
></ha-config-cloud-register>
|
||||
</template>
|
||||
|
||||
<template
|
||||
is="dom-if"
|
||||
if='[[_equals(_routeData.page, "forgot-password")]]'
|
||||
restamp=""
|
||||
>
|
||||
<ha-config-cloud-forgot-password
|
||||
page-name="forgot-password"
|
||||
hass="[[hass]]"
|
||||
email="{{_loginEmail}}"
|
||||
></ha-config-cloud-forgot-password>
|
||||
</template>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
isWide: Boolean,
|
||||
loadingAccount: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
cloudStatus: {
|
||||
type: Object,
|
||||
},
|
||||
_flashMessage: {
|
||||
type: String,
|
||||
value: "",
|
||||
},
|
||||
|
||||
route: Object,
|
||||
|
||||
_routeData: Object,
|
||||
_routeTail: Object,
|
||||
_loginEmail: String,
|
||||
};
|
||||
}
|
||||
|
||||
static get observers() {
|
||||
return ["_checkRoute(route, cloudStatus)"];
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener("cloud-done", (ev) => {
|
||||
this._flashMessage = ev.detail.flashMessage;
|
||||
this.navigate("/config/cloud/login");
|
||||
});
|
||||
}
|
||||
|
||||
_checkRoute(route) {
|
||||
this._debouncer = Debouncer.debounce(
|
||||
this._debouncer,
|
||||
timeOut.after(0),
|
||||
() => {
|
||||
if (
|
||||
!this.cloudStatus ||
|
||||
(!this.cloudStatus.logged_in &&
|
||||
!NOT_LOGGED_IN_URLS.includes(route.path))
|
||||
) {
|
||||
this.navigate("/config/cloud/login", true);
|
||||
} else if (
|
||||
this.cloudStatus.logged_in &&
|
||||
!LOGGED_IN_URLS.includes(route.path)
|
||||
) {
|
||||
this.navigate("/config/cloud/account", true);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_equals(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-config-cloud", HaConfigCloud);
|
134
src/panels/config/cloud/ha-config-cloud.ts
Normal file
134
src/panels/config/cloud/ha-config-cloud.ts
Normal file
@ -0,0 +1,134 @@
|
||||
import "./ha-config-cloud-account";
|
||||
import "./ha-config-cloud-login";
|
||||
import {
|
||||
HassRouterPage,
|
||||
RouterOptions,
|
||||
} from "../../../layouts/hass-router-page";
|
||||
import { property, customElement } from "lit-element";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { CloudStatus } from "../../../data/cloud";
|
||||
import { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import { PolymerElement } from "@polymer/polymer";
|
||||
|
||||
const LOGGED_IN_URLS = ["account"];
|
||||
const NOT_LOGGED_IN_URLS = ["login", "register", "forgot-password"];
|
||||
|
||||
@customElement("ha-config-cloud")
|
||||
class HaConfigCloud extends HassRouterPage {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public isWide!: boolean;
|
||||
@property() public route!: Route;
|
||||
@property() public cloudStatus!: CloudStatus;
|
||||
|
||||
protected routerOptions: RouterOptions = {
|
||||
defaultPage: "login",
|
||||
showLoading: true,
|
||||
initialLoad: () => this._cloudStatusLoaded,
|
||||
// Guard the different pages based on if we're logged in.
|
||||
beforeRender: (page: string) => {
|
||||
if (this.cloudStatus.logged_in) {
|
||||
if (!LOGGED_IN_URLS.includes(page)) {
|
||||
return "account";
|
||||
}
|
||||
} else {
|
||||
if (!NOT_LOGGED_IN_URLS.includes(page)) {
|
||||
return "login";
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
routes: {
|
||||
login: {
|
||||
tag: "ha-config-cloud-login",
|
||||
},
|
||||
register: {
|
||||
tag: "ha-config-cloud-register",
|
||||
load: () => import("./ha-config-cloud-register"),
|
||||
},
|
||||
"forgot-password": {
|
||||
tag: "ha-config-cloud-forgot-password",
|
||||
load: () => import("./ha-config-cloud-forgot-password"),
|
||||
},
|
||||
account: {
|
||||
tag: "ha-config-cloud-account",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@property() private _flashMessage = "";
|
||||
@property() private _loginEmail = "";
|
||||
private _resolveCloudStatusLoaded!: () => void;
|
||||
private _cloudStatusLoaded = new Promise((resolve) => {
|
||||
this._resolveCloudStatusLoaded = resolve;
|
||||
});
|
||||
|
||||
protected firstUpdated(changedProps) {
|
||||
super.firstUpdated(changedProps);
|
||||
this.addEventListener("cloud-done", (ev) => {
|
||||
this._flashMessage = (ev as any).detail.flashMessage;
|
||||
navigate(this, "/config/cloud/login");
|
||||
});
|
||||
}
|
||||
|
||||
protected updated(changedProps) {
|
||||
super.updated(changedProps);
|
||||
|
||||
if (changedProps.has("cloudStatus")) {
|
||||
const oldStatus = changedProps.get("cloudStatus") as
|
||||
| CloudStatus
|
||||
| undefined;
|
||||
if (oldStatus === undefined) {
|
||||
this._resolveCloudStatusLoaded();
|
||||
} else if (oldStatus.logged_in !== this.cloudStatus.logged_in) {
|
||||
navigate(this, this.route.prefix, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected createElement(tag: string) {
|
||||
const el = super.createElement(tag);
|
||||
el.addEventListener("email-changed", (ev) => {
|
||||
this._loginEmail = (ev as PolymerChangedEvent<string>).detail.value;
|
||||
});
|
||||
el.addEventListener("flash-message-changed", (ev) => {
|
||||
this._flashMessage = (ev as PolymerChangedEvent<string>).detail.value;
|
||||
});
|
||||
return el;
|
||||
}
|
||||
|
||||
protected updatePageEl(el) {
|
||||
// We are not going to update if the current page if we are not logged in
|
||||
// and the current page requires being logged in. Happens when we log out.
|
||||
if (
|
||||
this.cloudStatus &&
|
||||
!this.cloudStatus.logged_in &&
|
||||
LOGGED_IN_URLS.includes(this._currentPage)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ("setProperties" in el) {
|
||||
// As long as we have Polymer pages
|
||||
(el as PolymerElement).setProperties({
|
||||
hass: this.hass,
|
||||
email: this._loginEmail,
|
||||
isWide: this.isWide,
|
||||
cloudStatus: this.cloudStatus,
|
||||
flashMessage: this._flashMessage,
|
||||
});
|
||||
} else {
|
||||
el.hass = this.hass;
|
||||
el.email = this._loginEmail;
|
||||
el.isWide = this.isWide;
|
||||
el.cloudStatus = this.cloudStatus;
|
||||
el.flashMessage = this._flashMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-config-cloud": HaConfigCloud;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user