From 8ad5280501e3e5b91a48f740df39956bb3c11616 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 25 Nov 2018 20:47:29 +0100 Subject: [PATCH] Document types in fireEvent (#2108) * Document types in fireEvent * Fix more types for fireEvent * Adjust new code to new fireEvent --- .../dom/{fire_event.js => fire_event.ts} | 41 ++++++++++---- src/layouts/app/dialog-manager-mixin.js | 25 --------- src/layouts/app/dialog-manager-mixin.ts | 56 +++++++++++++++++++ src/layouts/app/home-assistant.js | 4 +- .../lovelace/cards/hui-picture-glance-card.ts | 2 +- src/panels/lovelace/common/handle-click.ts | 4 +- .../lovelace/components/hui-card-options.ts | 10 ++++ .../components/hui-theme-select-editor.ts | 13 ++++- .../lovelace/editor/hui-dialog-edit-card.ts | 16 +++++- .../lovelace/editor/hui-dialog-save-config.ts | 7 +++ src/panels/lovelace/editor/hui-edit-card.ts | 15 +++++ src/polymer-types.ts | 15 +++++ 12 files changed, 166 insertions(+), 42 deletions(-) rename src/common/dom/{fire_event.js => fire_event.ts} (72%) delete mode 100644 src/layouts/app/dialog-manager-mixin.js create mode 100644 src/layouts/app/dialog-manager-mixin.ts create mode 100644 src/polymer-types.ts diff --git a/src/common/dom/fire_event.js b/src/common/dom/fire_event.ts similarity index 72% rename from src/common/dom/fire_event.js rename to src/common/dom/fire_event.ts index c9e6785b2a..57ecbd02c3 100644 --- a/src/common/dom/fire_event.js +++ b/src/common/dom/fire_event.ts @@ -28,6 +28,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +declare global { + // tslint:disable-next-line + interface HASSDomEvents {} +} + +export type ValidHassDomEvent = keyof HASSDomEvents; + +export interface HASSDomEvent extends Event { + detail: T; +} + /** * Dispatches a custom event with an optional detail value. * @@ -35,23 +46,33 @@ * @param {*=} detail Detail value containing event-specific * payload. * @param {{ bubbles: (boolean|undefined), - cancelable: (boolean|undefined), - composed: (boolean|undefined) }=} - * options Object specifying options. These may include: - * `bubbles` (boolean, defaults to `true`), - * `cancelable` (boolean, defaults to false), and - * `node` on which to fire the event (HTMLElement, defaults to `this`). - * @return {Event} The new event that was fired. - */ -export const fireEvent = (node, type, detail, options) => { + * cancelable: (boolean|undefined), + * composed: (boolean|undefined) }=} + * options Object specifying options. These may include: + * `bubbles` (boolean, defaults to `true`), + * `cancelable` (boolean, defaults to false), and + * `node` on which to fire the event (HTMLElement, defaults to `this`). + * @return {Event} The new event that was fired. + */ +export const fireEvent = ( + node: HTMLElement, + type: HassEvent, + detail?: HASSDomEvents[HassEvent], + options?: { + bubbles?: boolean; + cancelable?: boolean; + composed?: boolean; + } +) => { options = options || {}; + // @ts-ignore detail = detail === null || detail === undefined ? {} : detail; const event = new Event(type, { bubbles: options.bubbles === undefined ? true : options.bubbles, cancelable: Boolean(options.cancelable), composed: options.composed === undefined ? true : options.composed, }); - event.detail = detail; + (event as any).detail = detail; node.dispatchEvent(event); return event; }; diff --git a/src/layouts/app/dialog-manager-mixin.js b/src/layouts/app/dialog-manager-mixin.js deleted file mode 100644 index 7deeaa2fd0..0000000000 --- a/src/layouts/app/dialog-manager-mixin.js +++ /dev/null @@ -1,25 +0,0 @@ -export default (superClass) => - class extends superClass { - ready() { - super.ready(); - this.addEventListener("register-dialog", (e) => - this.registerDialog(e.detail) - ); - } - - registerDialog({ dialogShowEvent, dialogTag, dialogImport }) { - let loaded = null; - - this.addEventListener(dialogShowEvent, (showEv) => { - if (!loaded) { - loaded = dialogImport().then(() => { - const dialogEl = document.createElement(dialogTag); - this.shadowRoot.appendChild(dialogEl); - this.provideHass(dialogEl); - return dialogEl; - }); - } - loaded.then((dialogEl) => dialogEl.showDialog(showEv.detail)); - }); - } - }; diff --git a/src/layouts/app/dialog-manager-mixin.ts b/src/layouts/app/dialog-manager-mixin.ts new file mode 100644 index 0000000000..90295c3866 --- /dev/null +++ b/src/layouts/app/dialog-manager-mixin.ts @@ -0,0 +1,56 @@ +import { PolymerElement } from "@polymer/polymer"; +import { Constructor } from "@polymer/lit-element"; +import { HASSDomEvent, ValidHassDomEvent } from "../../common/dom/fire_event"; + +interface RegisterDialogParams { + dialogShowEvent: keyof HASSDomEvents; + dialogTag: keyof HTMLElementTagNameMap; + dialogImport: () => Promise; +} + +interface HassDialog extends HTMLElement { + showDialog(params: T); +} + +declare global { + // for fire event + interface HASSDomEvents { + "register-dialog": RegisterDialogParams; + } + // for add event listener + interface HTMLElementEventMap { + "register-dialog": HASSDomEvent; + } +} + +export const dialogManagerMixin = (superClass: Constructor) => + class extends superClass { + public ready() { + super.ready(); + this.addEventListener("register-dialog", (e) => + this.registerDialog(e.detail) + ); + } + + private registerDialog({ + dialogShowEvent, + dialogTag, + dialogImport, + }: RegisterDialogParams) { + let loaded: Promise>; + + this.addEventListener(dialogShowEvent, (showEv) => { + if (!loaded) { + loaded = dialogImport().then(() => { + const dialogEl = document.createElement(dialogTag) as HassDialog; + this.shadowRoot!.appendChild(dialogEl); + (this as any).provideHass(dialogEl); + return dialogEl; + }); + } + loaded.then((dialogEl) => + dialogEl.showDialog((showEv as HASSDomEvent).detail) + ); + }); + } + }; diff --git a/src/layouts/app/home-assistant.js b/src/layouts/app/home-assistant.js index 1d05e2bd1a..27983b1e3c 100644 --- a/src/layouts/app/home-assistant.js +++ b/src/layouts/app/home-assistant.js @@ -16,7 +16,7 @@ import TranslationsMixin from "./translations-mixin"; import ThemesMixin from "./themes-mixin"; import MoreInfoMixin from "./more-info-mixin"; import SidebarMixin from "./sidebar-mixin"; -import DialogManagerMixin from "./dialog-manager-mixin"; +import { dialogManagerMixin } from "./dialog-manager-mixin"; import ConnectionMixin from "./connection-mixin"; import NotificationMixin from "./notification-mixin"; import DisconnectToastMixin from "./disconnect-toast-mixin"; @@ -33,7 +33,7 @@ class HomeAssistant extends ext(PolymerElement, [ DisconnectToastMixin, ConnectionMixin, NotificationMixin, - DialogManagerMixin, + dialogManagerMixin, HassBaseMixin, ]) { static get template() { diff --git a/src/panels/lovelace/cards/hui-picture-glance-card.ts b/src/panels/lovelace/cards/hui-picture-glance-card.ts index 776126ddb6..8853146118 100644 --- a/src/panels/lovelace/cards/hui-picture-glance-card.ts +++ b/src/panels/lovelace/cards/hui-picture-glance-card.ts @@ -180,7 +180,7 @@ class HuiPictureGlanceCard extends hassLocalizeLitMixin(LitElement) navigate(this, this._config!.navigation_path!); } else if (this._config!.camera_image) { fireEvent(this, "hass-more-info", { - entityId: this._config!.camera_image, + entityId: this._config!.camera_image!, }); } } diff --git a/src/panels/lovelace/common/handle-click.ts b/src/panels/lovelace/common/handle-click.ts index f420a0f39a..714f4217eb 100644 --- a/src/panels/lovelace/common/handle-click.ts +++ b/src/panels/lovelace/common/handle-click.ts @@ -22,7 +22,9 @@ export const handleClick = ( switch (action) { case "more-info": - fireEvent(node, "hass-more-info", { entityId: config.entity }); + if (config.entity) { + fireEvent(node, "hass-more-info", { entityId: config.entity }); + } break; case "navigate": navigate(node, config.navigation_path ? config.navigation_path : ""); diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index ebd0767251..8cc1ab6a85 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -8,6 +8,16 @@ import { import { HomeAssistant } from "../../../types"; import { LovelaceCardConfig } from "../types"; +declare global { + // for fire event + interface HASSDomEvents { + "show-edit-card": { + cardConfig: LovelaceCardConfig; + reloadLovelace: () => void; + }; + } +} + let registeredDialog = false; export class HuiCardOptions extends LitElement { diff --git a/src/panels/lovelace/components/hui-theme-select-editor.ts b/src/panels/lovelace/components/hui-theme-select-editor.ts index 71c9017183..206919b213 100644 --- a/src/panels/lovelace/components/hui-theme-select-editor.ts +++ b/src/panels/lovelace/components/hui-theme-select-editor.ts @@ -3,9 +3,20 @@ import "@polymer/paper-button/paper-button"; import { TemplateResult } from "lit-html"; import { HomeAssistant } from "../../../types"; -import { fireEvent } from "../../../common/dom/fire_event"; +import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event"; import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin"; +declare global { + // for fire event + interface HASSDomEvents { + "theme-changed": undefined; + } + // for add event listener + interface HTMLElementEventMap { + "theme-changed": HASSDomEvent; + } +} + export class HuiThemeSelectionEditor extends hassLocalizeLitMixin(LitElement) { public value?: string; protected hass?: HomeAssistant; diff --git a/src/panels/lovelace/editor/hui-dialog-edit-card.ts b/src/panels/lovelace/editor/hui-dialog-edit-card.ts index b8cbe5b835..741ac97497 100644 --- a/src/panels/lovelace/editor/hui-dialog-edit-card.ts +++ b/src/panels/lovelace/editor/hui-dialog-edit-card.ts @@ -2,11 +2,23 @@ import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element"; import { TemplateResult } from "lit-html"; import { HomeAssistant } from "../../../types"; +import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event"; import { LovelaceCardConfig } from "../types"; -import { fireEvent } from "../../../common/dom/fire_event"; import "./hui-edit-card"; import "./hui-migrate-config"; +declare global { + // for fire event + interface HASSDomEvents { + "reload-lovelace": undefined; + "show-edit-card": EditCardDialogParams; + } + // for add event listener + interface HTMLElementEventMap { + "reload-lovelace": HASSDomEvent; + } +} + const dialogShowEvent = "show-edit-card"; const dialogTag = "hui-dialog-edit-config"; @@ -69,7 +81,7 @@ export class HuiDialogEditCard extends LitElement { declare global { interface HTMLElementTagNameMap { - "hui-dialog-edit-card": HuiDialogEditCard; + "hui-dialog-edit-config": HuiDialogEditCard; } } diff --git a/src/panels/lovelace/editor/hui-dialog-save-config.ts b/src/panels/lovelace/editor/hui-dialog-save-config.ts index e5c0f01985..de759c54cf 100644 --- a/src/panels/lovelace/editor/hui-dialog-save-config.ts +++ b/src/panels/lovelace/editor/hui-dialog-save-config.ts @@ -15,6 +15,13 @@ import { saveConfig, migrateConfig } from "../common/data"; import { fireEvent } from "../../../common/dom/fire_event"; import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin"; +declare global { + // for fire event + interface HASSDomEvents { + "show-save-config": SaveDialogParams; + } +} + const dialogShowEvent = "show-save-config"; const dialogTag = "hui-dialog-save-config"; diff --git a/src/panels/lovelace/editor/hui-edit-card.ts b/src/panels/lovelace/editor/hui-edit-card.ts index 166b8913d1..1814b62df8 100644 --- a/src/panels/lovelace/editor/hui-edit-card.ts +++ b/src/panels/lovelace/editor/hui-edit-card.ts @@ -24,6 +24,21 @@ import { HuiCardPreview } from "./hui-card-preview"; import { LovelaceCardEditor, LovelaceCardConfig } from "../types"; import { YamlChangedEvent, ConfigValue, ConfigError } from "./types"; import { extYamlSchema } from "./yaml-ext-schema"; +import { EntityConfig } from "../entity-rows/types"; + +declare global { + interface HASSDomEvents { + "yaml-changed": { + yaml: string; + }; + "entities-changed": { + entities: EntityConfig[]; + }; + "config-changed": { + config: LovelaceCardConfig; + }; + } +} const CUSTOM_TYPE_PREFIX = "custom:"; diff --git a/src/polymer-types.ts b/src/polymer-types.ts new file mode 100644 index 0000000000..d38ee79cc4 --- /dev/null +++ b/src/polymer-types.ts @@ -0,0 +1,15 @@ +// Force file to be a module to augment global scope. +export {}; + +declare global { + // for fire event + interface HASSDomEvents { + "iron-resize": undefined; + "config-refresh": undefined; + "ha-refresh-cloud-status": undefined; + "hass-more-info": { + entityId: string; + }; + "location-changed": undefined; + } +}