Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions src/common/dom/fire_event.js → src/common/dom/fire_event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,51 @@
// (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<T> extends Event {
detail: T;
}

/**
* Dispatches a custom event with an optional detail value.
*
* @param {string} type Name of event type.
* @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 = <HassEvent extends ValidHassDomEvent>(
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;
};
25 changes: 0 additions & 25 deletions src/layouts/app/dialog-manager-mixin.js

This file was deleted.

56 changes: 56 additions & 0 deletions src/layouts/app/dialog-manager-mixin.ts
Original file line number Diff line number Diff line change
@@ -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<unknown>;
}

interface HassDialog<T = HASSDomEvents[ValidHassDomEvent]> extends HTMLElement {
showDialog(params: T);
}

declare global {
// for fire event
interface HASSDomEvents {
"register-dialog": RegisterDialogParams;
}
// for add event listener
interface HTMLElementEventMap {
"register-dialog": HASSDomEvent<RegisterDialogParams>;
}
}

export const dialogManagerMixin = (superClass: Constructor<PolymerElement>) =>
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<HassDialog<unknown>>;

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<unknown>).detail)
);
});
}
};
4 changes: 2 additions & 2 deletions src/layouts/app/home-assistant.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -33,7 +33,7 @@ class HomeAssistant extends ext(PolymerElement, [
DisconnectToastMixin,
ConnectionMixin,
NotificationMixin,
DialogManagerMixin,
dialogManagerMixin,
HassBaseMixin,
]) {
static get template() {
Expand Down
2 changes: 1 addition & 1 deletion src/panels/lovelace/cards/hui-picture-glance-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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!,
});
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/panels/lovelace/common/handle-click.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 : "");
Expand Down
10 changes: 10 additions & 0 deletions src/panels/lovelace/components/hui-card-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 12 additions & 1 deletion src/panels/lovelace/components/hui-theme-select-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<undefined>;
}
}

export class HuiThemeSelectionEditor extends hassLocalizeLitMixin(LitElement) {
public value?: string;
protected hass?: HomeAssistant;
Expand Down
16 changes: 14 additions & 2 deletions src/panels/lovelace/editor/hui-dialog-edit-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<undefined>;
}
}

const dialogShowEvent = "show-edit-card";
const dialogTag = "hui-dialog-edit-config";

Expand Down Expand Up @@ -69,7 +81,7 @@ export class HuiDialogEditCard extends LitElement {

declare global {
interface HTMLElementTagNameMap {
"hui-dialog-edit-card": HuiDialogEditCard;
"hui-dialog-edit-config": HuiDialogEditCard;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bramkragten my fireEvent work found this bug because it verifies that the dialog tag that you try to register is a known element 👍

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit-card is better than edit-config I think, but good thing you found it.

}
}

Expand Down
7 changes: 7 additions & 0 deletions src/panels/lovelace/editor/hui-dialog-save-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
15 changes: 15 additions & 0 deletions src/panels/lovelace/editor/hui-edit-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:";

Expand Down
15 changes: 15 additions & 0 deletions src/polymer-types.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}