From f8ea7e0ef253d6e78001ec6a259e38a7ebbf03a3 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 13 Jun 2023 15:24:36 +0200 Subject: [PATCH] Make actions available as event (#16839) --- src/panels/lovelace/cards/hui-button-card.ts | 21 ++++++++------ src/panels/lovelace/common/handle-action.ts | 16 ++++++----- src/state/action-mixin.ts | 30 ++++++++++++++++++++ src/state/hass-element.ts | 2 ++ 4 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 src/state/action-mixin.ts diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts index 1e9167e5a4..b98607fcc2 100644 --- a/src/panels/lovelace/cards/hui-button-card.ts +++ b/src/panels/lovelace/cards/hui-button-card.ts @@ -8,12 +8,12 @@ import { HassEntity, } from "home-assistant-js-websocket"; import { - CSSResultGroup, - LitElement, - PropertyValues, css, + CSSResultGroup, html, + LitElement, nothing, + PropertyValues, } from "lit"; import { customElement, eventOptions, queryAsync, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; @@ -21,6 +21,7 @@ import { styleMap } from "lit/directives/style-map"; import { DOMAINS_TOGGLE } from "../../../common/const"; import { transform } from "../../../common/decorators/transform"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; +import { fireEvent } from "../../../common/dom/fire_event"; import { computeDomain } from "../../../common/entity/compute_domain"; import { computeStateDisplaySingleEntity } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; @@ -28,6 +29,7 @@ import { computeStateName } from "../../../common/entity/compute_state_name"; import { stateColorCss } from "../../../common/entity/state_color"; import { isValidEntityId } from "../../../common/entity/valid_entity_id"; import { iconColorCSS } from "../../../common/style/icon_color_css"; +import { LocalizeFunc } from "../../../common/translations/localize"; import "../../../components/ha-card"; import { HVAC_ACTION_TO_MODE } from "../../../data/climate"; import { @@ -38,20 +40,18 @@ import { statesContext, themesContext, } from "../../../data/context"; +import { EntityRegistryDisplayEntry } from "../../../data/entity_registry"; import { LightEntity } from "../../../data/light"; import { ActionHandlerEvent } from "../../../data/lovelace"; +import { FrontendLocaleData } from "../../../data/translation"; +import { Themes } from "../../../data/ws-themes"; import { HomeAssistant } from "../../../types"; import { actionHandler } from "../common/directives/action-handler-directive"; import { findEntities } from "../common/find-entities"; -import { handleAction } from "../common/handle-action"; import { hasAction } from "../common/has-action"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { ButtonCardConfig } from "./types"; -import { LocalizeFunc } from "../../../common/translations/localize"; -import { FrontendLocaleData } from "../../../data/translation"; -import { Themes } from "../../../data/ws-themes"; -import { EntityRegistryDisplayEntry } from "../../../data/entity_registry"; @customElement("hui-button-card") export class HuiButtonCard extends LitElement implements LovelaceCard { @@ -364,7 +364,10 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { } private _handleAction(ev: ActionHandlerEvent) { - handleAction(this, this.hass!, this._config!, ev.detail.action!); + fireEvent(this, "hass-action", { + config: this._config!, + action: ev.detail.action, + }); } } diff --git a/src/panels/lovelace/common/handle-action.ts b/src/panels/lovelace/common/handle-action.ts index ddbbc838f3..7ea895d723 100644 --- a/src/panels/lovelace/common/handle-action.ts +++ b/src/panels/lovelace/common/handle-action.ts @@ -14,16 +14,18 @@ declare global { } } +export type ActionConfigParams = { + entity?: string; + camera_image?: string; + hold_action?: ActionConfig; + tap_action?: ActionConfig; + double_tap_action?: ActionConfig; +}; + export const handleAction = async ( node: HTMLElement, hass: HomeAssistant, - config: { - entity?: string; - camera_image?: string; - hold_action?: ActionConfig; - tap_action?: ActionConfig; - double_tap_action?: ActionConfig; - }, + config: ActionConfigParams, action: string ): Promise => { let actionConfig: ActionConfig | undefined; diff --git a/src/state/action-mixin.ts b/src/state/action-mixin.ts new file mode 100644 index 0000000000..5a583bfc62 --- /dev/null +++ b/src/state/action-mixin.ts @@ -0,0 +1,30 @@ +import type { PropertyValues } from "lit"; +import type { HASSDomEvent } from "../common/dom/fire_event"; +import { + ActionConfigParams, + handleAction, +} from "../panels/lovelace/common/handle-action"; +import type { Constructor } from "../types"; +import type { HassBaseEl } from "./hass-base-mixin"; + +declare global { + // for fire event + interface HASSDomEvents { + "hass-action": { config: ActionConfigParams; action: string }; + } +} + +export default >(superClass: T) => + class extends superClass { + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + this.addEventListener("hass-action", (ev) => this._handleAction(ev)); + } + + private async _handleAction( + ev: HASSDomEvent<{ config: ActionConfigParams; action: string }> + ) { + if (!this.hass) return; + handleAction(this, this.hass, ev.detail.config, ev.detail.action); + } + }; diff --git a/src/state/hass-element.ts b/src/state/hass-element.ts index e6e5b9f67a..e017d5c3ef 100644 --- a/src/state/hass-element.ts +++ b/src/state/hass-element.ts @@ -8,6 +8,7 @@ import { HassBaseEl } from "./hass-base-mixin"; import { loggingMixin } from "./logging-mixin"; import { contextMixin } from "./context-mixin"; import MoreInfoMixin from "./more-info-mixin"; +import ActionMixin from "./action-mixin"; import NotificationMixin from "./notification-mixin"; import { panelTitleMixin } from "./panel-title-mixin"; import SidebarMixin from "./sidebar-mixin"; @@ -23,6 +24,7 @@ export class HassElement extends ext(HassBaseEl, [ ThemesMixin, TranslationsMixin, MoreInfoMixin, + ActionMixin, SidebarMixin, DisconnectToastMixin, connectionMixin,