From 3f7c29a6f604bae3efc7ccbf579bb2b6d6203942 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Fri, 14 Feb 2020 03:56:08 -0600 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20change=20entity-button=20t?= =?UTF-8?q?o=20button=20card=20(#4581)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ♻️ change entity-button to button card * maintain separate entity-button class --- demo/src/configs/teachingbirds/lovelace.ts | 20 +- .../src/demos/demo-hui-entity-button-card.ts | 18 +- src/panels/lovelace/cards/hui-button-card.ts | 256 ++++++++++++++++++ .../lovelace/cards/hui-entity-button-card.ts | 243 +---------------- src/panels/lovelace/cards/types.ts | 4 +- .../create-element/create-card-element.ts | 2 + .../editor/card-editor/hui-card-picker.ts | 2 +- ...rd-editor.ts => hui-button-card-editor.ts} | 14 +- src/translations/en.json | 4 +- 9 files changed, 292 insertions(+), 271 deletions(-) create mode 100644 src/panels/lovelace/cards/hui-button-card.ts rename src/panels/lovelace/editor/config-elements/{hui-entity-button-card-editor.ts => hui-button-card-editor.ts} (94%) diff --git a/demo/src/configs/teachingbirds/lovelace.ts b/demo/src/configs/teachingbirds/lovelace.ts index 45443fddcc..5fbe14ff0a 100644 --- a/demo/src/configs/teachingbirds/lovelace.ts +++ b/demo/src/configs/teachingbirds/lovelace.ts @@ -395,7 +395,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ cards: [ { entity: "script.air_cleaner_quiet", - type: "entity-button", + type: "button", name: "AC bed", tap_action: { action: "call-service", @@ -408,7 +408,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ }, { entity: "script.air_cleaner_auto", - type: "entity-button", + type: "button", name: "AC bed", tap_action: { action: "call-service", @@ -421,7 +421,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ }, { entity: "script.air_cleaner_turbo", - type: "entity-button", + type: "button", name: "AC bed", tap_action: { action: "call-service", @@ -434,7 +434,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ }, { entity: "script.ac_off", - type: "entity-button", + type: "button", name: "AC", tap_action: { action: "call-service", @@ -447,7 +447,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ }, { entity: "script.ac_on", - type: "entity-button", + type: "button", name: "AC", tap_action: { action: "call-service", @@ -658,7 +658,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ action: "call-service", service: "script.goodnight", }, - type: "entity-button", + type: "button", icon: "mdi:weather-night", }, { @@ -670,7 +670,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ }, service: "scene.turn_on", }, - type: "entity-button", + type: "button", icon: "mdi:coffee-outline", }, { @@ -682,7 +682,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ }, service: "scene.turn_on", }, - type: "entity-button", + type: "button", icon: "mdi:television-classic", }, ], @@ -743,7 +743,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ }, service: "light.toggle", }, - type: "entity-button", + type: "button", icon: "mdi:page-layout-footer", }, { @@ -755,7 +755,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ }, service: "light.toggle", }, - type: "entity-button", + type: "button", icon: "mdi:page-layout-header", }, ], diff --git a/gallery/src/demos/demo-hui-entity-button-card.ts b/gallery/src/demos/demo-hui-entity-button-card.ts index f5d877fe73..254dc3f006 100644 --- a/gallery/src/demos/demo-hui-entity-button-card.ts +++ b/gallery/src/demos/demo-hui-entity-button-card.ts @@ -15,14 +15,14 @@ const CONFIGS = [ { heading: "Basic example", config: ` -- type: entity-button +- type: button entity: light.bed_light `, }, { heading: "With Name", config: ` -- type: entity-button +- type: button name: Bedroom entity: light.bed_light `, @@ -30,7 +30,7 @@ const CONFIGS = [ { heading: "With Icon", config: ` -- type: entity-button +- type: button entity: light.bed_light icon: mdi:hotel `, @@ -38,7 +38,7 @@ const CONFIGS = [ { heading: "Without State", config: ` -- type: entity-button +- type: button entity: light.bed_light show_state: false `, @@ -46,7 +46,7 @@ const CONFIGS = [ { heading: "Custom Tap Action (toggle)", config: ` -- type: entity-button +- type: button entity: light.bed_light tap_action: action: toggle @@ -55,7 +55,7 @@ const CONFIGS = [ { heading: "Running Service", config: ` -- type: entity-button +- type: button entity: light.bed_light service: light.toggle `, @@ -63,13 +63,13 @@ const CONFIGS = [ { heading: "Invalid Entity", config: ` -- type: entity-button +- type: button entity: sensor.invalid_entity `, }, ]; -class DemoEntityButtonEntity extends PolymerElement { +class DemoButtonEntity extends PolymerElement { static get template() { return html` { + await import( + /* webpackChunkName: "hui-button-card-editor" */ "../editor/config-elements/hui-button-card-editor" + ); + return document.createElement("hui-button-card-editor"); + } + + public static getStubConfig(): object { + return { + tap_action: { action: "toggle" }, + hold_action: { action: "more-info" }, + show_icon: true, + show_name: true, + }; + } + + @property() public hass?: HomeAssistant; + + @property() private _config?: ButtonCardConfig; + + public getCardSize(): number { + return 2; + } + + public setConfig(config: ButtonCardConfig): void { + if (config.entity && !isValidEntityId(config.entity)) { + throw new Error("Invalid Entity"); + } + + this._config = { + theme: "default", + hold_action: { action: "more-info" }, + double_tap_action: { action: "none" }, + show_icon: true, + show_name: true, + ...config, + }; + + if (config.entity && DOMAINS_TOGGLE.has(computeDomain(config.entity))) { + this._config = { + tap_action: { + action: "toggle", + }, + ...this._config, + }; + } else { + this._config = { + tap_action: { + action: "more-info", + }, + ...this._config, + }; + } + } + + protected shouldUpdate(changedProps: PropertyValues): boolean { + if (changedProps.has("_config")) { + return true; + } + + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + + if ( + !oldHass || + oldHass.themes !== this.hass!.themes || + oldHass.language !== this.hass!.language + ) { + return true; + } + + return ( + Boolean(this._config!.entity) && + oldHass.states[this._config!.entity!] !== + this.hass!.states[this._config!.entity!] + ); + } + + protected render(): TemplateResult { + if (!this._config || !this.hass) { + return html``; + } + const stateObj = this._config.entity + ? this.hass.states[this._config.entity] + : undefined; + + if (this._config.entity && !stateObj) { + return html` + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} + `; + } + + return html` + + ${this._config.show_icon + ? html` + + ` + : ""} + ${this._config.show_name + ? html` + + ${this._config.name || + (stateObj ? computeStateName(stateObj) : "")} + + ` + : ""} + + + `; + } + + protected updated(changedProps: PropertyValues): void { + super.updated(changedProps); + if (!this._config || !this.hass) { + return; + } + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + const oldConfig = changedProps.get("_config") as + | ButtonCardConfig + | undefined; + + if ( + !oldHass || + !oldConfig || + oldHass.themes !== this.hass.themes || + oldConfig.theme !== this._config.theme + ) { + applyThemesOnElement(this, this.hass.themes, this._config.theme); + } + } + + static get styles(): CSSResult { + return css` + ha-card { + cursor: pointer; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: 4% 0; + font-size: 1.2rem; + } + + ha-card:focus { + outline: none; + background: var(--divider-color); + } + + ha-icon { + width: 40%; + height: auto; + color: var(--paper-item-icon-color, #44739e); + } + + ${iconColorCSS} + `; + } + + private _computeBrightness(stateObj: HassEntity | LightEntity): string { + if (!stateObj.attributes.brightness) { + return ""; + } + const brightness = stateObj.attributes.brightness; + return `brightness(${(brightness + 245) / 5}%)`; + } + + private _computeColor(stateObj: HassEntity | LightEntity): string { + if (!stateObj.attributes.hs_color) { + return ""; + } + const [hue, sat] = stateObj.attributes.hs_color; + if (sat <= 10) { + return ""; + } + return `hsl(${hue}, 100%, ${100 - sat / 2}%)`; + } + + private _handleAction(ev: ActionHandlerEvent) { + handleAction(this, this.hass!, this._config!, ev.detail.action!); + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-button-card": HuiButtonCard; + } +} diff --git a/src/panels/lovelace/cards/hui-entity-button-card.ts b/src/panels/lovelace/cards/hui-entity-button-card.ts index 707e4f60ed..e062d189a2 100644 --- a/src/panels/lovelace/cards/hui-entity-button-card.ts +++ b/src/panels/lovelace/cards/hui-entity-button-card.ts @@ -1,246 +1,9 @@ -import { - html, - LitElement, - PropertyValues, - TemplateResult, - CSSResult, - css, - customElement, - property, -} from "lit-element"; -import { HassEntity } from "home-assistant-js-websocket"; -import { styleMap } from "lit-html/directives/style-map"; -import { ifDefined } from "lit-html/directives/if-defined"; -import "@material/mwc-ripple"; +import { customElement } from "lit-element"; -import "../../../components/ha-card"; -import "../components/hui-warning"; - -import { isValidEntityId } from "../../../common/entity/valid_entity_id"; -import { stateIcon } from "../../../common/entity/state_icon"; -import { computeStateDomain } from "../../../common/entity/compute_state_domain"; -import { computeStateName } from "../../../common/entity/compute_state_name"; -import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; -import { computeDomain } from "../../../common/entity/compute_domain"; - -import { HomeAssistant, LightEntity } from "../../../types"; -import { LovelaceCard, LovelaceCardEditor } from "../types"; -import { DOMAINS_TOGGLE } from "../../../common/const"; -import { EntityButtonCardConfig } from "./types"; -import { actionHandler } from "../common/directives/action-handler-directive"; -import { hasAction } from "../common/has-action"; -import { handleAction } from "../common/handle-action"; -import { ActionHandlerEvent } from "../../../data/lovelace"; -import { computeActiveState } from "../../../common/entity/compute_active_state"; -import { iconColorCSS } from "../../../common/style/icon_color_css"; +import { HuiButtonCard } from "./hui-button-card"; @customElement("hui-entity-button-card") -class HuiEntityButtonCard extends LitElement implements LovelaceCard { - public static async getConfigElement(): Promise { - await import( - /* webpackChunkName: "hui-entity-button-card-editor" */ "../editor/config-elements/hui-entity-button-card-editor" - ); - return document.createElement("hui-entity-button-card-editor"); - } - - public static getStubConfig(): object { - return { - tap_action: { action: "toggle" }, - hold_action: { action: "more-info" }, - show_icon: true, - show_name: true, - }; - } - - @property() public hass?: HomeAssistant; - - @property() private _config?: EntityButtonCardConfig; - - public getCardSize(): number { - return 2; - } - - public setConfig(config: EntityButtonCardConfig): void { - if (!isValidEntityId(config.entity)) { - throw new Error("Invalid Entity"); - } - - this._config = { - theme: "default", - hold_action: { action: "more-info" }, - double_tap_action: { action: "none" }, - show_icon: true, - show_name: true, - ...config, - }; - - if (DOMAINS_TOGGLE.has(computeDomain(config.entity))) { - this._config = { - tap_action: { - action: "toggle", - }, - ...this._config, - }; - } else { - this._config = { - tap_action: { - action: "more-info", - }, - ...this._config, - }; - } - } - - protected shouldUpdate(changedProps: PropertyValues): boolean { - if (changedProps.has("_config")) { - return true; - } - - const oldHass = changedProps.get("hass") as HomeAssistant | undefined; - - if ( - !oldHass || - oldHass.themes !== this.hass!.themes || - oldHass.language !== this.hass!.language - ) { - return true; - } - - return ( - oldHass.states[this._config!.entity] !== - this.hass!.states[this._config!.entity] - ); - } - - protected render(): TemplateResult { - if (!this._config || !this.hass) { - return html``; - } - const stateObj = this.hass.states[this._config.entity]; - - if (!stateObj) { - return html` - ${this.hass.localize( - "ui.panel.lovelace.warning.entity_not_found", - "entity", - this._config.entity - )} - `; - } - - return html` - - ${this._config.show_icon - ? html` - - ` - : ""} - ${this._config.show_name - ? html` - - ${this._config.name || computeStateName(stateObj)} - - ` - : ""} - - - `; - } - - protected updated(changedProps: PropertyValues): void { - super.updated(changedProps); - if (!this._config || !this.hass) { - return; - } - const oldHass = changedProps.get("hass") as HomeAssistant | undefined; - const oldConfig = changedProps.get("_config") as - | EntityButtonCardConfig - | undefined; - - if ( - !oldHass || - !oldConfig || - oldHass.themes !== this.hass.themes || - oldConfig.theme !== this._config.theme - ) { - applyThemesOnElement(this, this.hass.themes, this._config.theme); - } - } - - static get styles(): CSSResult { - return css` - ha-card { - cursor: pointer; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - padding: 4% 0; - font-size: 1.2rem; - } - - ha-card:focus { - outline: none; - } - - ha-icon { - width: 40%; - height: auto; - color: var(--paper-item-icon-color, #44739e); - } - - ${iconColorCSS} - `; - } - - private _computeBrightness(stateObj: HassEntity | LightEntity): string { - if (!stateObj.attributes.brightness) { - return ""; - } - const brightness = stateObj.attributes.brightness; - return `brightness(${(brightness + 245) / 5}%)`; - } - - private _computeColor(stateObj: HassEntity | LightEntity): string { - if (!stateObj.attributes.hs_color) { - return ""; - } - const [hue, sat] = stateObj.attributes.hs_color; - if (sat <= 10) { - return ""; - } - return `hsl(${hue}, 100%, ${100 - sat / 2}%)`; - } - - private _handleAction(ev: ActionHandlerEvent) { - handleAction(this, this.hass!, this._config!, ev.detail.action!); - } -} +class HuiEntityButtonCard extends HuiButtonCard {} declare global { interface HTMLElementTagNameMap { diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index b90f11e9f8..ffc361e64d 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -47,8 +47,8 @@ export interface EntitiesCardConfig extends LovelaceCardConfig { state_color?: boolean; } -export interface EntityButtonCardConfig extends LovelaceCardConfig { - entity: string; +export interface ButtonCardConfig extends LovelaceCardConfig { + entity?: string; name?: string; show_name?: boolean; icon?: string; diff --git a/src/panels/lovelace/create-element/create-card-element.ts b/src/panels/lovelace/create-element/create-card-element.ts index 6692a1ea3d..74f171580f 100644 --- a/src/panels/lovelace/create-element/create-card-element.ts +++ b/src/panels/lovelace/create-element/create-card-element.ts @@ -1,4 +1,5 @@ import "../cards/hui-entities-card"; +import "../cards/hui-button-card"; import "../cards/hui-entity-button-card"; import "../cards/hui-glance-card"; import "../cards/hui-history-graph-card"; @@ -14,6 +15,7 @@ import { createLovelaceElement } from "./create-element-base"; const ALWAYS_LOADED_TYPES = new Set([ "entities", + "button", "entity-button", "error", "glance", diff --git a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts index 45315fb8f9..422e24d86b 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts @@ -18,7 +18,7 @@ const cards: string[] = [ "alarm-panel", "conditional", "entities", - "entity-button", + "button", "entity-filter", "gauge", "glance", diff --git a/src/panels/lovelace/editor/config-elements/hui-entity-button-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts similarity index 94% rename from src/panels/lovelace/editor/config-elements/hui-entity-button-card-editor.ts rename to src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts index 8cf5027a6c..c4d760094d 100644 --- a/src/panels/lovelace/editor/config-elements/hui-entity-button-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts @@ -22,7 +22,7 @@ import { LovelaceCardEditor } from "../../types"; import { fireEvent } from "../../../../common/dom/fire_event"; import { configElementStyle } from "./config-elements-style"; import { ActionConfig } from "../../../../data/lovelace"; -import { EntityButtonCardConfig } from "../../cards/types"; +import { ButtonCardConfig } from "../../cards/types"; const cardConfigStruct = struct({ type: "string", @@ -37,14 +37,14 @@ const cardConfigStruct = struct({ theme: "string?", }); -@customElement("hui-entity-button-card-editor") -export class HuiEntityButtonCardEditor extends LitElement +@customElement("hui-button-card-editor") +export class HuiButtonCardEditor extends LitElement implements LovelaceCardEditor { @property() public hass?: HomeAssistant; - @property() private _config?: EntityButtonCardConfig; + @property() private _config?: ButtonCardConfig; - public setConfig(config: EntityButtonCardConfig): void { + public setConfig(config: ButtonCardConfig): void { config = cardConfigStruct(config); this._config = config; } @@ -108,7 +108,7 @@ export class HuiEntityButtonCardEditor extends LitElement .label="${this.hass.localize( "ui.panel.lovelace.editor.card.generic.entity" )} (${this.hass.localize( - "ui.panel.lovelace.editor.card.config.required" + "ui.panel.lovelace.editor.card.config.optional" )})" .hass="${this.hass}" .value="${this._entity}" @@ -250,6 +250,6 @@ export class HuiEntityButtonCardEditor extends LitElement declare global { interface HTMLElementTagNameMap { - "hui-entity-button-card-editor": HuiEntityButtonCardEditor; + "hui-button-card-editor": HuiButtonCardEditor; } } diff --git a/src/translations/en.json b/src/translations/en.json index 9aab1d472e..771ac55b29 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1811,8 +1811,8 @@ "show_header_toggle": "Show Header Toggle?", "toggle": "Toggle entities." }, - "entity-button": { - "name": "Entity Button" + "button": { + "name": "Button" }, "entity-filter": { "name": "Entity Filter"