From 58e6be12af96e2cda67407616a8cbe9e71144613 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 28 Jun 2019 08:34:29 -0700 Subject: [PATCH] Add developer tools panel (#3313) --- build-scripts/gulp/gen-icons.js | 1 + src/components/ha-sidebar.ts | 157 ++++--------- src/layouts/partial-panel-resolver.ts | 25 +- src/panels/dev-info/ha-panel-dev-info.ts | 221 ------------------ .../developer-tools/developer-tools-router.ts | 68 ++++++ .../event/developer-tools-event.js} | 75 +++--- .../event}/event-subscribe-card.ts | 8 +- .../event}/events-list.js | 2 +- .../ha-panel-developer-tools.ts | 121 ++++++++++ .../info/developer-tools-info.ts | 194 +++++++++++++++ .../info}/dialog-system-log-detail.ts | 6 +- .../info}/error-log-card.ts | 4 +- .../info}/show-dialog-system-log-detail.ts | 4 +- .../info}/system-health-card.ts | 6 +- .../info}/system-log-card.ts | 14 +- .../mqtt/developer-tools-mqtt.js} | 10 +- .../service/developer-tools-service.js} | 183 +++++++-------- .../state/developer-tools-state.js} | 197 +++++++--------- .../template/developer-tools-template.js} | 89 +++---- 19 files changed, 710 insertions(+), 675 deletions(-) delete mode 100644 src/panels/dev-info/ha-panel-dev-info.ts create mode 100644 src/panels/developer-tools/developer-tools-router.ts rename src/panels/{dev-event/ha-panel-dev-event.js => developer-tools/event/developer-tools-event.js} (55%) rename src/panels/{dev-event => developer-tools/event}/event-subscribe-card.ts (93%) rename src/panels/{dev-event => developer-tools/event}/events-list.js (95%) create mode 100644 src/panels/developer-tools/ha-panel-developer-tools.ts create mode 100644 src/panels/developer-tools/info/developer-tools-info.ts rename src/panels/{dev-info => developer-tools/info}/dialog-system-log-detail.ts (91%) rename src/panels/{dev-info => developer-tools/info}/error-log-card.ts (93%) rename src/panels/{dev-info => developer-tools/info}/show-dialog-system-log-detail.ts (88%) rename src/panels/{dev-info => developer-tools/info}/system-health-card.ts (95%) rename src/panels/{dev-info => developer-tools/info}/system-log-card.ts (91%) rename src/panels/{dev-mqtt/ha-panel-dev-mqtt.js => developer-tools/mqtt/developer-tools-mqtt.js} (90%) rename src/panels/{dev-service/ha-panel-dev-service.js => developer-tools/service/developer-tools-service.js} (55%) rename src/panels/{dev-state/ha-panel-dev-state.js => developer-tools/state/developer-tools-state.js} (60%) rename src/panels/{dev-template/ha-panel-dev-template.js => developer-tools/template/developer-tools-template.js} (66%) diff --git a/build-scripts/gulp/gen-icons.js b/build-scripts/gulp/gen-icons.js index bfa7d7cc77..11548794c4 100644 --- a/build-scripts/gulp/gen-icons.js +++ b/build-scripts/gulp/gen-icons.js @@ -22,6 +22,7 @@ const BUILT_IN_PANEL_ICONS = [ "mailbox", // Mailbox "tooltip-account", // Map "cart", // Shopping List + "hammer", // developer-tools ]; // Given an icon name, load the SVG file diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts index 8bb0bcc131..c326d3778e 100644 --- a/src/components/ha-sidebar.ts +++ b/src/components/ha-sidebar.ts @@ -14,7 +14,6 @@ import "@polymer/paper-listbox/paper-listbox"; import "./ha-icon"; import "../components/user/ha-user-badge"; -import isComponentLoaded from "../common/config/is_component_loaded"; import { HomeAssistant, PanelInfo } from "../types"; import { fireEvent } from "../common/dom/fire_event"; import { DEFAULT_PANEL } from "../common/const"; @@ -23,47 +22,64 @@ import { ExternalConfig, } from "../external_app/external_config"; +const SHOW_AFTER_SPACER = ["config", "developer-tools"]; + const computeUrl = (urlPath) => `/${urlPath}`; -const computePanels = (hass: HomeAssistant) => { +const SORT_VALUE = { + map: 1, + logbook: 2, + history: 3, + "developer-tools": 9, + configuration: 10, +}; + +const panelSorter = (a, b) => { + const aBuiltIn = a.component_name in SORT_VALUE; + const bBuiltIn = b.component_name in SORT_VALUE; + + if (aBuiltIn && bBuiltIn) { + return SORT_VALUE[a.component_name] - SORT_VALUE[b.component_name]; + } + if (aBuiltIn) { + return -1; + } + if (bBuiltIn) { + return 1; + } + // both not built in, sort by title + if (a.title! < b.title!) { + return -1; + } + if (a.title! > b.title!) { + return 1; + } + return 0; +}; + +const computePanels = (hass: HomeAssistant): [PanelInfo[], PanelInfo[]] => { const panels = hass.panels; if (!panels) { - return []; + return [[], []]; } - const sortValue = { - map: 1, - logbook: 2, - history: 3, - }; - const result: PanelInfo[] = Object.values(panels).filter( - (panel) => panel.title - ); + const beforeSpacer: PanelInfo[] = []; + const afterSpacer: PanelInfo[] = []; - result.sort((a, b) => { - const aBuiltIn = a.component_name in sortValue; - const bBuiltIn = b.component_name in sortValue; - - if (aBuiltIn && bBuiltIn) { - return sortValue[a.component_name] - sortValue[b.component_name]; + Object.values(panels).forEach((panel) => { + if (!panel.title) { + return; } - if (aBuiltIn) { - return -1; - } - if (bBuiltIn) { - return 1; - } - // both not built in, sort by title - if (a.title! < b.title!) { - return -1; - } - if (a.title! > b.title!) { - return 1; - } - return 0; + (SHOW_AFTER_SPACER.includes(panel.component_name) + ? afterSpacer + : beforeSpacer + ).push(panel); }); - return result; + beforeSpacer.sort(panelSorter); + afterSpacer.sort(panelSorter); + + return [beforeSpacer, afterSpacer]; }; const renderPanel = (hass, panel) => html` @@ -100,12 +116,7 @@ class HaSidebar extends LitElement { return html``; } - const panels = computePanels(hass); - const configPanelIdx = panels.findIndex( - (panel) => panel.component_name === "config" - ); - const configPanel = - configPanelIdx === -1 ? undefined : panels.splice(configPanelIdx, 1)[0]; + const [beforeSpacer, afterSpacer] = computePanels(hass); return html` ${this.expanded @@ -137,69 +148,11 @@ class HaSidebar extends LitElement { - ${panels.map((panel) => renderPanel(hass, panel))} + ${beforeSpacer.map((panel) => renderPanel(hass, panel))}
- ${this.expanded && hass.user && hass.user.is_admin - ? html` -
- -
- ${hass.localize("ui.sidebar.developer_tools")} -
- -
- - - - - - - - - - - - - ${isComponentLoaded(hass, "mqtt") - ? html` - - - - ` - : html``} - - - -
-
- ` - : ""} + ${afterSpacer.map((panel) => renderPanel(hass, panel))} ${this._externalConfig && this._externalConfig.hasSettingsScreen ? html` ` : ""} - ${configPanel ? renderPanel(hass, configPanel) : ""} ${hass.user ? html` import(/* webpackChunkName: "panel-calendar" */ "../panels/calendar/ha-panel-calendar"), @@ -17,18 +17,8 @@ const COMPONENTS = { import(/* webpackChunkName: "panel-config" */ "../panels/config/ha-panel-config"), custom: () => import(/* webpackChunkName: "panel-custom" */ "../panels/custom/ha-panel-custom"), - "dev-event": () => - import(/* webpackChunkName: "panel-dev-event" */ "../panels/dev-event/ha-panel-dev-event"), - "dev-info": () => - import(/* webpackChunkName: "panel-dev-info" */ "../panels/dev-info/ha-panel-dev-info"), - "dev-mqtt": () => - import(/* webpackChunkName: "panel-dev-mqtt" */ "../panels/dev-mqtt/ha-panel-dev-mqtt"), - "dev-service": () => - import(/* webpackChunkName: "panel-dev-service" */ "../panels/dev-service/ha-panel-dev-service"), - "dev-state": () => - import(/* webpackChunkName: "panel-dev-state" */ "../panels/dev-state/ha-panel-dev-state"), - "dev-template": () => - import(/* webpackChunkName: "panel-dev-template" */ "../panels/dev-template/ha-panel-dev-template"), + "developer-tools": () => + import(/* webpackChunkName: "panel-developer-tools" */ "../panels/developer-tools/ha-panel-developer-tools"), lovelace: () => import(/* webpackChunkName: "panel-lovelace" */ "../panels/lovelace/ha-panel-lovelace"), states: () => @@ -52,14 +42,17 @@ const COMPONENTS = { }; const getRoutes = (panels: Panels): RouterOptions => { - const routes: { [route: string]: RouteOptions } = {}; + const routes: RouterOptions["routes"] = {}; Object.values(panels).forEach((panel) => { - routes[panel.url_path] = { - load: COMPONENTS[panel.component_name], + const data: RouteOptions = { tag: `ha-panel-${panel.component_name}`, cache: CACHE_COMPONENTS.includes(panel.component_name), }; + if (panel.component_name in COMPONENTS) { + data.load = COMPONENTS[panel.component_name]; + } + routes[panel.url_path] = data; }); return { diff --git a/src/panels/dev-info/ha-panel-dev-info.ts b/src/panels/dev-info/ha-panel-dev-info.ts deleted file mode 100644 index 970030790f..0000000000 --- a/src/panels/dev-info/ha-panel-dev-info.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { - LitElement, - html, - PropertyDeclarations, - CSSResult, - css, - TemplateResult, -} from "lit-element"; -import "@polymer/app-layout/app-header-layout/app-header-layout"; -import "@polymer/app-layout/app-header/app-header"; -import "@polymer/app-layout/app-toolbar/app-toolbar"; -import "../../components/ha-menu-button"; - -import { HomeAssistant } from "../../types"; -import { haStyle } from "../../resources/styles"; - -import "./system-log-card"; -import "./error-log-card"; -import "./system-health-card"; - -const JS_VERSION = __BUILD__; -const OPT_IN_PANEL = "states"; - -class HaPanelDevInfo extends LitElement { - public hass?: HomeAssistant; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - }; - } - - protected render(): TemplateResult | void { - const hass = this.hass; - if (!hass) { - return html``; - } - const customUiList: Array<{ name: string; url: string; version: string }> = - (window as any).CUSTOM_UI_LIST || []; - - const nonDefaultLink = - localStorage.defaultPage === OPT_IN_PANEL && OPT_IN_PANEL === "states" - ? "/lovelace" - : "/states"; - - const nonDefaultLinkText = - localStorage.defaultPage === OPT_IN_PANEL && OPT_IN_PANEL === "states" - ? "Go to the Lovelace UI" - : "Go to the states UI"; - - const defaultPageText = `${ - localStorage.defaultPage === OPT_IN_PANEL ? "Remove" : "Set" - } ${OPT_IN_PANEL} as default page on this device`; - - return html` - - - - -
About
-
-
- -
-
-

- - Home Assistant logo - -
- Home Assistant
- ${hass.config.version} -

-

- Path to configuration.yaml: ${hass.config.config_dir} -

-

- - Developed by a bunch of awesome people. - -

-

- Published under the Apache 2.0 license
- Source: - server - — - frontend-ui -

-

- Built using - Python 3, - Polymer, Icons by - Google - and - MaterialDesignIcons.com. -

-

- Frontend JavaScript version: ${JS_VERSION} - ${customUiList.length > 0 - ? html` -

- Custom UIs: - ${customUiList.map( - (item) => html` -
- - ${item.name}: ${item.version} -
- ` - )} -
- ` - : ""} -

-

- ${nonDefaultLinkText}
- - ${defaultPageText} - -

-
- - - -
- - `; - } - - protected firstUpdated(changedProps): void { - super.firstUpdated(changedProps); - - // Legacy custom UI can be slow to register, give them time. - const customUI = ((window as any).CUSTOM_UI_LIST || []).length; - setTimeout(() => { - if (((window as any).CUSTOM_UI_LIST || []).length !== customUI.length) { - this.requestUpdate(); - } - }, 1000); - } - - protected _toggleDefaultPage(): void { - if (localStorage.defaultPage === OPT_IN_PANEL) { - delete localStorage.defaultPage; - } else { - localStorage.defaultPage = OPT_IN_PANEL; - } - this.requestUpdate(); - } - - static get styles(): CSSResult[] { - return [ - haStyle, - css` - :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; - } - - .content { - padding: 16px 0px 16px 0; - direction: ltr; - } - - .about { - text-align: center; - line-height: 2em; - } - - .version { - @apply --paper-font-headline; - } - - .develop { - @apply --paper-font-subhead; - } - - .about a { - color: var(--dark-primary-color); - } - - system-health-card { - display: block; - max-width: 600px; - margin: 0 auto; - } - `, - ]; - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-panel-dev-info": HaPanelDevInfo; - } -} - -customElements.define("ha-panel-dev-info", HaPanelDevInfo); diff --git a/src/panels/developer-tools/developer-tools-router.ts b/src/panels/developer-tools/developer-tools-router.ts new file mode 100644 index 0000000000..924c82232e --- /dev/null +++ b/src/panels/developer-tools/developer-tools-router.ts @@ -0,0 +1,68 @@ +import { HassRouterPage, RouterOptions } from "../../layouts/hass-router-page"; +import { customElement, property } from "lit-element"; +import { PolymerElement } from "@polymer/polymer"; +import { HomeAssistant } from "../../types"; + +@customElement("developer-tools-router") +class DeveloperToolsRouter extends HassRouterPage { + @property() public hass!: HomeAssistant; + @property() public narrow!: boolean; + + protected routerOptions: RouterOptions = { + // defaultPage: "info", + beforeRender: (page) => { + if (!page || page === "not_found") { + // If we can, we are going to restore the last visited page. + return this._currentPage ? this._currentPage : "info"; + } + return undefined; + }, + cacheAll: true, + showLoading: true, + routes: { + event: { + tag: "developer-tools-event", + load: () => import("./event/developer-tools-event"), + }, + info: { + tag: "developer-tools-info", + load: () => import("./info/developer-tools-info"), + }, + mqtt: { + tag: "developer-tools-mqtt", + load: () => import("./mqtt/developer-tools-mqtt"), + }, + service: { + tag: "developer-tools-service", + load: () => import("./service/developer-tools-service"), + }, + state: { + tag: "developer-tools-state", + load: () => import("./state/developer-tools-state"), + }, + template: { + tag: "developer-tools-template", + load: () => import("./template/developer-tools-template"), + }, + }, + }; + + protected updatePageEl(el) { + if ("setProperties" in el) { + // As long as we have Polymer pages + (el as PolymerElement).setProperties({ + hass: this.hass, + narrow: this.narrow, + }); + } else { + el.hass = this.hass; + el.narrow = this.narrow; + } + } +} + +declare global { + interface HTMLElementTagNameMap { + "developer-tools-router": DeveloperToolsRouter; + } +} diff --git a/src/panels/dev-event/ha-panel-dev-event.js b/src/panels/developer-tools/event/developer-tools-event.js similarity index 55% rename from src/panels/dev-event/ha-panel-dev-event.js rename to src/panels/developer-tools/event/developer-tools-event.js index d5cc9d9551..dd772af390 100644 --- a/src/panels/dev-event/ha-panel-dev-event.js +++ b/src/panels/developer-tools/event/developer-tools-event.js @@ -1,6 +1,3 @@ -import "@polymer/app-layout/app-header-layout/app-header-layout"; -import "@polymer/app-layout/app-header/app-header"; -import "@polymer/app-layout/app-toolbar/app-toolbar"; import "@polymer/iron-flex-layout/iron-flex-layout-classes"; import "@material/mwc-button"; import "@polymer/paper-input/paper-input"; @@ -8,11 +5,10 @@ import "@polymer/paper-input/paper-textarea"; import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; -import "../../components/ha-menu-button"; -import "../../resources/ha-style"; +import "../../../resources/ha-style"; import "./events-list"; import "./event-subscribe-card"; -import { EventsMixin } from "../../mixins/events-mixin"; +import { EventsMixin } from "../../../mixins/events-mixin"; /* * @appliesMixin EventsMixin @@ -26,12 +22,10 @@ class HaPanelDevEvent extends EventsMixin(PolymerElement) { -ms-user-select: initial; -webkit-user-select: initial; -moz-user-select: initial; - } - - .content { @apply --paper-font-body1; padding: 16px; direction: ltr; + display: block; } .ha-form { @@ -49,45 +43,34 @@ class HaPanelDevEvent extends EventsMixin(PolymerElement) { } - - - - -
Events
-
-
+
+
+

Fire an event on the event bus.

-
-
-
-

Fire an event on the event bus.

- -
- - - Fire Event -
-
- -
-
Available Events
- -
+
+ + + Fire Event
-
- + +
+
Available Events
+ +
+
+ `; } @@ -139,4 +122,4 @@ class HaPanelDevEvent extends EventsMixin(PolymerElement) { } } -customElements.define("ha-panel-dev-event", HaPanelDevEvent); +customElements.define("developer-tools-event", HaPanelDevEvent); diff --git a/src/panels/dev-event/event-subscribe-card.ts b/src/panels/developer-tools/event/event-subscribe-card.ts similarity index 93% rename from src/panels/dev-event/event-subscribe-card.ts rename to src/panels/developer-tools/event/event-subscribe-card.ts index cc0196b235..4b56290f86 100644 --- a/src/panels/dev-event/event-subscribe-card.ts +++ b/src/panels/developer-tools/event/event-subscribe-card.ts @@ -10,10 +10,10 @@ import { import "@material/mwc-button"; import "@polymer/paper-input/paper-input"; import { HassEvent } from "home-assistant-js-websocket"; -import { HomeAssistant } from "../../types"; -import { PolymerChangedEvent } from "../../polymer-types"; -import "../../components/ha-card"; -import format_time from "../../common/datetime/format_time"; +import { HomeAssistant } from "../../../types"; +import { PolymerChangedEvent } from "../../../polymer-types"; +import "../../../components/ha-card"; +import format_time from "../../../common/datetime/format_time"; @customElement("event-subscribe-card") class EventSubscribeCard extends LitElement { diff --git a/src/panels/dev-event/events-list.js b/src/panels/developer-tools/event/events-list.js similarity index 95% rename from src/panels/dev-event/events-list.js rename to src/panels/developer-tools/event/events-list.js index f27d9bd929..3ffba2e5f5 100644 --- a/src/panels/dev-event/events-list.js +++ b/src/panels/developer-tools/event/events-list.js @@ -1,7 +1,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; -import { EventsMixin } from "../../mixins/events-mixin"; +import { EventsMixin } from "../../../mixins/events-mixin"; /* * @appliesMixin EventsMixin diff --git a/src/panels/developer-tools/ha-panel-developer-tools.ts b/src/panels/developer-tools/ha-panel-developer-tools.ts new file mode 100644 index 0000000000..09814ff47b --- /dev/null +++ b/src/panels/developer-tools/ha-panel-developer-tools.ts @@ -0,0 +1,121 @@ +import { + LitElement, + TemplateResult, + html, + CSSResultArray, + css, + customElement, + property, +} from "lit-element"; +import "@polymer/app-layout/app-header-layout/app-header-layout"; +import "@polymer/app-layout/app-header/app-header"; +import "@polymer/app-layout/app-toolbar/app-toolbar"; +import "@polymer/paper-icon-button/paper-icon-button"; +import "@polymer/paper-tabs/paper-tab"; +import "@polymer/paper-tabs/paper-tabs"; + +import "../../components/ha-menu-button"; +import "../../resources/ha-style"; +import "./developer-tools-router"; + +import scrollToTarget from "../../common/dom/scroll-to-target"; + +import { haStyle } from "../../resources/styles"; +import { HomeAssistant, Route } from "../../types"; +import { navigate } from "../../common/navigate"; +import isComponentLoaded from "../../common/config/is_component_loaded"; + +@customElement("ha-panel-developer-tools") +class PanelDeveloperTools extends LitElement { + @property() public hass!: HomeAssistant; + @property() public route!: Route; + @property() public narrow!: boolean; + + protected render(): TemplateResult | void { + const page = this._page; + return html` + + + + +
Developer Tools
+
+ + + ${this.hass.localize("panel.dev-info")} + + + ${this.hass.localize("panel.dev-events")} + + ${isComponentLoaded(this.hass, "mqtt") + ? html` + + ${this.hass.localize("panel.dev-mqtt")} + + ` + : ""} + + ${this.hass.localize("panel.dev-services")} + + + ${this.hass.localize("panel.dev-states")} + + + ${this.hass.localize("panel.dev-templates")} + + +
+ +
+ `; + } + + private handlePageSelected(ev) { + const newPage = ev.detail.item.getAttribute("page-name"); + if (newPage !== this._page) { + navigate(this, `/developer-tools/${newPage}`); + } + + scrollToTarget( + this, + // @ts-ignore + this.shadowRoot!.querySelector("app-header-layout").header.scrollTarget + ); + } + + private get _page() { + return this.route.path.substr(1); + } + + static get styles(): CSSResultArray { + return [ + haStyle, + css` + :host { + color: var(--primary-text-color); + --paper-card-header-color: var(--primary-text-color); + } + paper-tabs { + margin-left: 12px; + --paper-tabs-selection-bar-color: #fff; + text-transform: uppercase; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-panel-developer-tools": PanelDeveloperTools; + } +} diff --git a/src/panels/developer-tools/info/developer-tools-info.ts b/src/panels/developer-tools/info/developer-tools-info.ts new file mode 100644 index 0000000000..6e248a97c4 --- /dev/null +++ b/src/panels/developer-tools/info/developer-tools-info.ts @@ -0,0 +1,194 @@ +import { + LitElement, + html, + CSSResult, + css, + TemplateResult, + property, +} from "lit-element"; + +import { HomeAssistant } from "../../../types"; +import { haStyle } from "../../../resources/styles"; + +import "./system-log-card"; +import "./error-log-card"; +import "./system-health-card"; + +const JS_VERSION = __BUILD__; +const OPT_IN_PANEL = "states"; + +class HaPanelDevInfo extends LitElement { + @property() public hass!: HomeAssistant; + + protected render(): TemplateResult | void { + const hass = this.hass; + const customUiList: Array<{ name: string; url: string; version: string }> = + (window as any).CUSTOM_UI_LIST || []; + + const nonDefaultLink = + localStorage.defaultPage === OPT_IN_PANEL && OPT_IN_PANEL === "states" + ? "/lovelace" + : "/states"; + + const nonDefaultLinkText = + localStorage.defaultPage === OPT_IN_PANEL && OPT_IN_PANEL === "states" + ? "Go to the Lovelace UI" + : "Go to the states UI"; + + const defaultPageText = `${ + localStorage.defaultPage === OPT_IN_PANEL ? "Remove" : "Set" + } ${OPT_IN_PANEL} as default page on this device`; + + return html` +
+

+ Home Assistant logo +
+ Home Assistant
+ ${hass.config.version} +

+

+ Path to configuration.yaml: ${hass.config.config_dir} +

+

+ + Developed by a bunch of awesome people. + +

+

+ Published under the Apache 2.0 license
+ Source: + server + — + frontend-ui +

+

+ Built using + Python 3, + Polymer, + Icons by + Google + and + MaterialDesignIcons.com. +

+

+ Frontend JavaScript version: ${JS_VERSION} + ${customUiList.length > 0 + ? html` +

+ Custom UIs: + ${customUiList.map( + (item) => html` +
+ ${item.name}: + ${item.version} +
+ ` + )} +
+ ` + : ""} +

+

+ ${nonDefaultLinkText}
+ + ${defaultPageText} + +

+
+ + + + `; + } + + protected firstUpdated(changedProps): void { + super.firstUpdated(changedProps); + + // Legacy custom UI can be slow to register, give them time. + const customUI = ((window as any).CUSTOM_UI_LIST || []).length; + setTimeout(() => { + if (((window as any).CUSTOM_UI_LIST || []).length !== customUI.length) { + this.requestUpdate(); + } + }, 1000); + } + + protected _toggleDefaultPage(): void { + if (localStorage.defaultPage === OPT_IN_PANEL) { + delete localStorage.defaultPage; + } else { + localStorage.defaultPage = OPT_IN_PANEL; + } + this.requestUpdate(); + } + + static get styles(): CSSResult[] { + return [ + haStyle, + css` + :host { + -ms-user-select: initial; + -webkit-user-select: initial; + -moz-user-select: initial; + } + + .content { + padding: 16px 0px 16px 0; + direction: ltr; + } + + .about { + text-align: center; + line-height: 2em; + } + + .version { + @apply --paper-font-headline; + } + + .develop { + @apply --paper-font-subhead; + } + + .about a { + color: var(--dark-primary-color); + } + + system-health-card { + display: block; + max-width: 600px; + margin: 0 auto; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "developer-tools-info": HaPanelDevInfo; + } +} + +customElements.define("developer-tools-info", HaPanelDevInfo); diff --git a/src/panels/dev-info/dialog-system-log-detail.ts b/src/panels/developer-tools/info/dialog-system-log-detail.ts similarity index 91% rename from src/panels/dev-info/dialog-system-log-detail.ts rename to src/panels/developer-tools/info/dialog-system-log-detail.ts index 6ec2299a1b..eba62d72ac 100644 --- a/src/panels/dev-info/dialog-system-log-detail.ts +++ b/src/panels/developer-tools/info/dialog-system-log-detail.ts @@ -8,11 +8,11 @@ import { } from "lit-element"; import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; -import "../../components/dialog/ha-paper-dialog"; +import "../../../components/dialog/ha-paper-dialog"; import { SystemLogDetailDialogParams } from "./show-dialog-system-log-detail"; -import { PolymerChangedEvent } from "../../polymer-types"; -import { haStyleDialog } from "../../resources/styles"; +import { PolymerChangedEvent } from "../../../polymer-types"; +import { haStyleDialog } from "../../../resources/styles"; class DialogSystemLogDetail extends LitElement { private _params?: SystemLogDetailDialogParams; diff --git a/src/panels/dev-info/error-log-card.ts b/src/panels/developer-tools/info/error-log-card.ts similarity index 93% rename from src/panels/dev-info/error-log-card.ts rename to src/panels/developer-tools/info/error-log-card.ts index 46b4274492..9f2bfbd094 100644 --- a/src/panels/dev-info/error-log-card.ts +++ b/src/panels/developer-tools/info/error-log-card.ts @@ -9,8 +9,8 @@ import { import "@polymer/paper-icon-button/paper-icon-button"; import "@material/mwc-button"; -import { HomeAssistant } from "../../types"; -import { fetchErrorLog } from "../../data/error_log"; +import { HomeAssistant } from "../../../types"; +import { fetchErrorLog } from "../../../data/error_log"; class ErrorLogCard extends LitElement { public hass?: HomeAssistant; diff --git a/src/panels/dev-info/show-dialog-system-log-detail.ts b/src/panels/developer-tools/info/show-dialog-system-log-detail.ts similarity index 88% rename from src/panels/dev-info/show-dialog-system-log-detail.ts rename to src/panels/developer-tools/info/show-dialog-system-log-detail.ts index 3e1899495f..b1c378b5a5 100644 --- a/src/panels/dev-info/show-dialog-system-log-detail.ts +++ b/src/panels/developer-tools/info/show-dialog-system-log-detail.ts @@ -1,5 +1,5 @@ -import { fireEvent } from "../../common/dom/fire_event"; -import { LoggedError } from "../../data/system_log"; +import { fireEvent } from "../../../common/dom/fire_event"; +import { LoggedError } from "../../../data/system_log"; declare global { // for fire event diff --git a/src/panels/dev-info/system-health-card.ts b/src/panels/developer-tools/info/system-health-card.ts similarity index 95% rename from src/panels/dev-info/system-health-card.ts rename to src/panels/developer-tools/info/system-health-card.ts index 82159ed847..82b819bc32 100644 --- a/src/panels/dev-info/system-health-card.ts +++ b/src/panels/developer-tools/info/system-health-card.ts @@ -7,13 +7,13 @@ import { TemplateResult, } from "lit-element"; import "@polymer/paper-spinner/paper-spinner"; -import "../../components/ha-card"; +import "../../../components/ha-card"; -import { HomeAssistant } from "../../types"; +import { HomeAssistant } from "../../../types"; import { SystemHealthInfo, fetchSystemHealthInfo, -} from "../../data/system_health"; +} from "../../../data/system_health"; const sortKeys = (a: string, b: string) => { if (a === "homeassistant") { diff --git a/src/panels/dev-info/system-log-card.ts b/src/panels/developer-tools/info/system-log-card.ts similarity index 91% rename from src/panels/dev-info/system-log-card.ts rename to src/panels/developer-tools/info/system-log-card.ts index 0d1391c1ee..e3800dcfec 100644 --- a/src/panels/dev-info/system-log-card.ts +++ b/src/panels/developer-tools/info/system-log-card.ts @@ -10,13 +10,13 @@ import "@polymer/paper-icon-button/paper-icon-button"; import "@polymer/paper-item/paper-item-body"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-spinner/paper-spinner"; -import "../../components/ha-card"; -import "../../components/buttons/ha-call-service-button"; -import "../../components/buttons/ha-progress-button"; -import { HomeAssistant } from "../../types"; -import { LoggedError, fetchSystemLog } from "../../data/system_log"; -import formatDateTime from "../../common/datetime/format_date_time"; -import formatTime from "../../common/datetime/format_time"; +import "../../../components/ha-card"; +import "../../../components/buttons/ha-call-service-button"; +import "../../../components/buttons/ha-progress-button"; +import { HomeAssistant } from "../../../types"; +import { LoggedError, fetchSystemLog } from "../../../data/system_log"; +import formatDateTime from "../../../common/datetime/format_date_time"; +import formatTime from "../../../common/datetime/format_time"; import { showSystemLogDetailDialog } from "./show-dialog-system-log-detail"; const formatLogTime = (date, language: string) => { diff --git a/src/panels/dev-mqtt/ha-panel-dev-mqtt.js b/src/panels/developer-tools/mqtt/developer-tools-mqtt.js similarity index 90% rename from src/panels/dev-mqtt/ha-panel-dev-mqtt.js rename to src/panels/developer-tools/mqtt/developer-tools-mqtt.js index 98bca44d17..ffaded67c8 100644 --- a/src/panels/dev-mqtt/ha-panel-dev-mqtt.js +++ b/src/panels/developer-tools/mqtt/developer-tools-mqtt.js @@ -7,10 +7,10 @@ import "@polymer/paper-input/paper-textarea"; import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; -import "../../components/ha-card"; -import "../../components/ha-menu-button"; -import "../../resources/ha-style"; -import "../../util/app-localstorage-document"; +import "../../../components/ha-card"; +import "../../../components/ha-menu-button"; +import "../../../resources/ha-style"; +import "../../../util/app-localstorage-document"; class HaPanelDevMqtt extends PolymerElement { static get template() { @@ -86,4 +86,4 @@ class HaPanelDevMqtt extends PolymerElement { } } -customElements.define("ha-panel-dev-mqtt", HaPanelDevMqtt); +customElements.define("developer-tools-mqtt", HaPanelDevMqtt); diff --git a/src/panels/dev-service/ha-panel-dev-service.js b/src/panels/developer-tools/service/developer-tools-service.js similarity index 55% rename from src/panels/dev-service/ha-panel-dev-service.js rename to src/panels/developer-tools/service/developer-tools-service.js index b4b0be23fe..05b1e7e1bf 100644 --- a/src/panels/dev-service/ha-panel-dev-service.js +++ b/src/panels/developer-tools/service/developer-tools-service.js @@ -1,17 +1,13 @@ -import "@polymer/app-layout/app-header-layout/app-header-layout"; -import "@polymer/app-layout/app-header/app-header"; -import "@polymer/app-layout/app-toolbar/app-toolbar"; import "@material/mwc-button"; import "@polymer/paper-input/paper-textarea"; import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; -import { ENTITY_COMPONENT_DOMAINS } from "../../data/entity"; -import "../../components/entity/ha-entity-picker"; -import "../../components/ha-menu-button"; -import "../../components/ha-service-picker"; -import "../../resources/ha-style"; -import "../../util/app-localstorage-document"; +import { ENTITY_COMPONENT_DOMAINS } from "../../../data/entity"; +import "../../../components/entity/ha-entity-picker"; +import "../../../components/ha-service-picker"; +import "../../../resources/ha-style"; +import "../../../util/app-localstorage-document"; const ERROR_SENTINEL = {}; class HaPanelDevService extends PolymerElement { @@ -22,9 +18,7 @@ class HaPanelDevService extends PolymerElement { -ms-user-select: initial; -webkit-user-select: initial; -moz-user-select: initial; - } - - .content { + display: block; padding: 16px; direction: ltr; } @@ -81,100 +75,87 @@ class HaPanelDevService extends PolymerElement { } - - - - -
Services
-
-
+ + + + - - - - +
+

+ The service dev tool allows you to call any available service in Home + Assistant. +

-
-

- The service dev tool allows you to call any available service in - Home Assistant. -

- -
- + +