From 26d27f8be985e437a2dae054997ac2b514515899 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Wed, 1 Apr 2020 12:18:38 -0500 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20change=20call-service=20ro?= =?UTF-8?q?w=20to=20button=20row=20(#4744)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ♻️ change call-service row to button row * address comments * cleanup * address comments * remove unused function * address comments * super * Add CallServiceConfig back in * Update types.ts * Update types.ts Co-authored-by: Bram Kragten --- src/panels/lovelace/common/call-service.ts | 12 -- .../create-element/create-row-element.ts | 2 + src/panels/lovelace/entity-rows/types.ts | 11 +- .../lovelace/special-rows/hui-button-row.ts | 103 ++++++++++++++++++ .../special-rows/hui-call-service-row.ts | 91 ++++------------ 5 files changed, 136 insertions(+), 83 deletions(-) delete mode 100644 src/panels/lovelace/common/call-service.ts create mode 100644 src/panels/lovelace/special-rows/hui-button-row.ts diff --git a/src/panels/lovelace/common/call-service.ts b/src/panels/lovelace/common/call-service.ts deleted file mode 100644 index de3b39984b..0000000000 --- a/src/panels/lovelace/common/call-service.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { HomeAssistant } from "../../../types"; -import { CallServiceConfig } from "../entity-rows/types"; - -export const callService = ( - config: CallServiceConfig, - hass: HomeAssistant -): void => { - const entityId = config.entity; - const [domain, service] = config.service.split(".", 2); - const serviceData = { entity_id: entityId, ...config.service_data }; - hass.callService(domain, service, serviceData); -}; diff --git a/src/panels/lovelace/create-element/create-row-element.ts b/src/panels/lovelace/create-element/create-row-element.ts index 1c12fbf3e6..8fd0e6019e 100644 --- a/src/panels/lovelace/create-element/create-row-element.ts +++ b/src/panels/lovelace/create-element/create-row-element.ts @@ -4,6 +4,7 @@ import "../entity-rows/hui-script-entity-row"; import "../entity-rows/hui-sensor-entity-row"; import "../entity-rows/hui-text-entity-row"; import "../entity-rows/hui-toggle-entity-row"; +import "../special-rows/hui-button-row"; import "../special-rows/hui-attribute-row"; import "../special-rows/hui-call-service-row"; import { EntityConfig } from "../entity-rows/types"; @@ -16,6 +17,7 @@ const ALWAYS_LOADED_TYPES = new Set([ "sensor-entity", "text-entity", "toggle-entity", + "button", "call-service", ]); const LAZY_LOAD_TYPES = { diff --git a/src/panels/lovelace/entity-rows/types.ts b/src/panels/lovelace/entity-rows/types.ts index b113bf33ee..618db52747 100644 --- a/src/panels/lovelace/entity-rows/types.ts +++ b/src/panels/lovelace/entity-rows/types.ts @@ -1,5 +1,6 @@ import { HomeAssistant } from "../../../types"; import { Condition } from "../common/validate-condition"; +import { ActionConfig } from "../../../data/lovelace"; export interface EntityConfig { entity: string; @@ -30,9 +31,16 @@ export interface WeblinkConfig { } export interface CallServiceConfig extends EntityConfig { type: "call-service"; - action_name?: string; service: string; service_data?: { [key: string]: any }; + action_name?: string; +} +export interface ButtonRowConfig extends EntityConfig { + type: "button"; + action_name?: string; + tap_action?: ActionConfig; + hold_action?: ActionConfig; + double_tap_action?: ActionConfig; } export interface CastConfig { type: "cast"; @@ -54,6 +62,7 @@ export type LovelaceRowConfig = | WeblinkConfig | CallServiceConfig | CastConfig + | ButtonRowConfig | ButtonsRowConfig | ConditionalRowConfig | AttributeRowConfig; diff --git a/src/panels/lovelace/special-rows/hui-button-row.ts b/src/panels/lovelace/special-rows/hui-button-row.ts new file mode 100644 index 0000000000..58fa793b62 --- /dev/null +++ b/src/panels/lovelace/special-rows/hui-button-row.ts @@ -0,0 +1,103 @@ +import { + html, + LitElement, + TemplateResult, + customElement, + property, + css, + CSSResult, +} from "lit-element"; +import "@material/mwc-button"; + +import "../../../components/ha-icon"; + +import { LovelaceRow, ButtonRowConfig } from "../entity-rows/types"; +import { HomeAssistant } from "../../../types"; +import { actionHandler } from "../common/directives/action-handler-directive"; +import { hasAction } from "../common/has-action"; +import { ActionHandlerEvent } from "../../../data/lovelace"; +import { handleAction } from "../common/handle-action"; + +@customElement("hui-button-row") +export class HuiButtonRow extends LitElement implements LovelaceRow { + public hass?: HomeAssistant; + @property() private _config?: ButtonRowConfig; + + public setConfig(config: ButtonRowConfig): void { + if (!config) { + throw new Error("Error in card configuration."); + } + + if (!config.name) { + throw new Error("Error in card configuration. No name specified."); + } + + if (!config.tap_action) { + throw new Error("Error in card configuration. No action specified."); + } + + this._config = config; + } + + protected render(): TemplateResult { + if (!this._config) { + return html``; + } + + return html` + +
+
${this._config.name}
+ ${this._config.action_name + ? this._config.action_name + : this.hass!.localize("ui.card.service.run")} +
+ `; + } + + static get styles(): CSSResult { + return css` + :host { + display: flex; + align-items: center; + } + ha-icon { + padding: 8px; + color: var(--paper-item-icon-color); + } + .flex { + flex: 1; + overflow: hidden; + margin-left: 16px; + display: flex; + justify-content: space-between; + align-items: center; + } + .flex div { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + mwc-button { + margin-right: -0.57em; + } + `; + } + + private _handleAction(ev: ActionHandlerEvent) { + handleAction(this, this.hass!, this._config!, ev.detail.action!); + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-button-row": HuiButtonRow; + } +} diff --git a/src/panels/lovelace/special-rows/hui-call-service-row.ts b/src/panels/lovelace/special-rows/hui-call-service-row.ts index a1e20b5fb2..7f9fab6051 100644 --- a/src/panels/lovelace/special-rows/hui-call-service-row.ts +++ b/src/panels/lovelace/special-rows/hui-call-service-row.ts @@ -1,83 +1,34 @@ -import { - html, - LitElement, - TemplateResult, - customElement, - property, - css, - CSSResult, -} from "lit-element"; -import "@material/mwc-button"; +import { customElement } from "lit-element"; -import "../../../components/ha-icon"; - -import { callService } from "../common/call-service"; -import { LovelaceRow, CallServiceConfig } from "../entity-rows/types"; -import { HomeAssistant } from "../../../types"; +import { CallServiceConfig } from "../entity-rows/types"; +import { HuiButtonRow } from "./hui-button-row"; @customElement("hui-call-service-row") -class HuiCallServiceRow extends LitElement implements LovelaceRow { - public hass?: HomeAssistant; +export class HuiCallServiceRow extends HuiButtonRow { + public setConfig(config: any): void { + const callServiceConfig: CallServiceConfig = config; - @property() private _config?: CallServiceConfig; - - public setConfig(config: CallServiceConfig): void { - if (!config || !config.name || !config.service) { + if (!callServiceConfig) { throw new Error("Error in card configuration."); } - this._config = { icon: "hass:remote", ...config }; - } - - protected render(): TemplateResult { - if (!this._config) { - return html``; + if (!callServiceConfig.name) { + throw new Error("Error in card configuration. No name specified."); } - return html` - -
-
${this._config.name}
- ${this._config.action_name - ? this._config.action_name - : this.hass!.localize("ui.card.service.run")} -
- `; - } + if (!callServiceConfig.service) { + throw new Error("Error in card configuration. No service specified."); + } - static get styles(): CSSResult { - return css` - :host { - display: flex; - align-items: center; - } - ha-icon { - padding: 8px; - color: var(--paper-item-icon-color); - } - .flex { - flex: 1; - overflow: hidden; - margin-left: 16px; - display: flex; - justify-content: space-between; - align-items: center; - } - .flex div { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - mwc-button { - margin-right: -0.57em; - } - `; - } - - private _callService() { - callService(this._config!, this.hass!); + super.setConfig({ + tap_action: { + action: "call-service", + service: callServiceConfig.service, + service_data: callServiceConfig.service_data, + }, + ...callServiceConfig, + type: "button", + }); } }