From e8d84e8ba50d1c6dafce18d26e7af2cb8df6257f Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Tue, 12 Feb 2019 00:33:57 -0600 Subject: [PATCH 01/18] Convert notification-button to Lit/TS and add badge --- package.json | 2 + .../notifications/hui-notifications-button.js | 68 ------------------- .../notifications/hui-notifications-button.ts | 57 ++++++++++++++++ src/panels/lovelace/hui-root.ts | 7 ++ yarn.lock | 11 +++ 5 files changed, 77 insertions(+), 68 deletions(-) delete mode 100644 src/panels/lovelace/components/notifications/hui-notifications-button.js create mode 100644 src/panels/lovelace/components/notifications/hui-notifications-button.ts diff --git a/package.json b/package.json index 4577c34aed..f986dc0baa 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "@polymer/iron-pages": "^3.0.1", "@polymer/iron-resizable-behavior": "^3.0.1", "@polymer/neon-animation": "^3.0.1", + "@polymer/paper-badge": "^3.0.1", + "@polymer/paper-button": "^3.0.1", "@polymer/paper-card": "^3.0.1", "@polymer/paper-checkbox": "^3.0.1", "@polymer/paper-dialog": "^3.0.1", diff --git a/src/panels/lovelace/components/notifications/hui-notifications-button.js b/src/panels/lovelace/components/notifications/hui-notifications-button.js deleted file mode 100644 index 6ecf1ec920..0000000000 --- a/src/panels/lovelace/components/notifications/hui-notifications-button.js +++ /dev/null @@ -1,68 +0,0 @@ -import "@material/mwc-button"; -import "@polymer/paper-icon-button/paper-icon-button"; -import "@polymer/app-layout/app-toolbar/app-toolbar"; - -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import EventsMixin from "../../../../mixins/events-mixin"; - -/* - * @appliesMixin EventsMixin - */ -export class HuiNotificationsButton extends EventsMixin(PolymerElement) { - static get template() { - return html` - - - - `; - } - - static get properties() { - return { - open: { - type: Boolean, - notify: true, - }, - notifications: { - type: Array, - value: [], - }, - }; - } - - _clicked() { - this.open = true; - } - - _hasNotifications(notifications) { - return notifications.length > 0; - } -} -customElements.define("hui-notifications-button", HuiNotificationsButton); diff --git a/src/panels/lovelace/components/notifications/hui-notifications-button.ts b/src/panels/lovelace/components/notifications/hui-notifications-button.ts new file mode 100644 index 0000000000..8bff5f3a21 --- /dev/null +++ b/src/panels/lovelace/components/notifications/hui-notifications-button.ts @@ -0,0 +1,57 @@ +import { + html, + LitElement, + TemplateResult, + css, + CSSResult, + property, +} from "lit-element"; +import "@polymer/paper-badge/paper-badge"; +import "@polymer/paper-icon-button/paper-icon-button"; +import { fireEvent } from "../../../../common/dom/fire_event"; + +class HuiNotificationsButton extends LitElement { + @property() public notifications?: string[]; + @property() public open?: boolean; + + protected render(): TemplateResult | void { + return html` + + ${this.notifications + ? html` + + ` + : ""} + `; + } + + static get styles(): CSSResult[] { + return [ + css` + :host { + position: relative; + } + paper-badge { + left: 23px !important; + top: 0px !important; + } + `, + ]; + } + + private _clicked() { + this.open = true; + fireEvent(this, "open-changed"); + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-notifications-button": HuiNotificationsButton; + } +} + +customElements.define("hui-notifications-button", HuiNotificationsButton); diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 25dadaebb3..86376918b0 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -57,6 +57,13 @@ const JS_CACHE = {}; let loadedUnusedEntities = false; +declare global { + // tslint:disable-next-line + interface HASSDomEvents { + "open-changed": {}; + } +} + class HUIRoot extends LitElement { public narrow?: boolean; public showMenu?: boolean; diff --git a/yarn.lock b/yarn.lock index 318b196f2c..4a19d56968 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1148,6 +1148,17 @@ "@polymer/iron-selector" "^3.0.0-pre.26" "@polymer/polymer" "^3.0.0" +"@polymer/paper-badge@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@polymer/paper-badge/-/paper-badge-3.0.1.tgz#ea973090342c66f99ea6ef1d32fc534ee40630e8" + integrity sha512-9lHB/AFPuDAY/+OPNio1Mi6JUAM8yQqzJEAkk99IwcCl9VB6uCjlrXVfistrYIv7z+Wy4SZHNEtA6xR1+FhCDg== + dependencies: + "@polymer/iron-flex-layout" "^3.0.0-pre.26" + "@polymer/iron-icon" "^3.0.0-pre.26" + "@polymer/iron-resizable-behavior" "^3.0.0-pre.26" + "@polymer/paper-styles" "^3.0.0-pre.26" + "@polymer/polymer" "^3.0.0" + "@polymer/paper-behaviors@^3.0.0-pre.27": version "3.0.1" resolved "https://registry.yarnpkg.com/@polymer/paper-behaviors/-/paper-behaviors-3.0.1.tgz#83f1cd06489f484c1b108a2967fb01952df722ad" From 08222dfbec49100834b597755e9dfea0045efea7 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Tue, 12 Feb 2019 17:30:50 -0600 Subject: [PATCH 02/18] review comments --- .../components/notifications/hui-notifications-button.ts | 6 +++--- src/panels/lovelace/hui-root.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/panels/lovelace/components/notifications/hui-notifications-button.ts b/src/panels/lovelace/components/notifications/hui-notifications-button.ts index 8bff5f3a21..3eb69a243a 100644 --- a/src/panels/lovelace/components/notifications/hui-notifications-button.ts +++ b/src/panels/lovelace/components/notifications/hui-notifications-button.ts @@ -12,7 +12,7 @@ import { fireEvent } from "../../../../common/dom/fire_event"; class HuiNotificationsButton extends LitElement { @property() public notifications?: string[]; - @property() public open?: boolean; + @property() public opened?: boolean; protected render(): TemplateResult | void { return html` @@ -43,8 +43,8 @@ class HuiNotificationsButton extends LitElement { } private _clicked() { - this.open = true; - fireEvent(this, "open-changed"); + this.opened = true; + fireEvent(this, "opened", { value: this.opened }); } } diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 86376918b0..6d198621ef 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -60,7 +60,7 @@ let loadedUnusedEntities = false; declare global { // tslint:disable-next-line interface HASSDomEvents { - "open-changed": {}; + opened: {}; } } @@ -193,8 +193,8 @@ class HUIRoot extends LitElement {
${this.config.title || "Home Assistant"}
Date: Wed, 13 Feb 2019 00:01:07 -0600 Subject: [PATCH 03/18] address review comments --- .../components/notifications/hui-notifications-button.ts | 2 +- src/panels/lovelace/hui-root.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/components/notifications/hui-notifications-button.ts b/src/panels/lovelace/components/notifications/hui-notifications-button.ts index 3eb69a243a..169c1cc4c1 100644 --- a/src/panels/lovelace/components/notifications/hui-notifications-button.ts +++ b/src/panels/lovelace/components/notifications/hui-notifications-button.ts @@ -22,7 +22,7 @@ class HuiNotificationsButton extends LitElement { > ${this.notifications ? html` - + ` : ""} `; diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 6d198621ef..f5398d139c 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -60,7 +60,7 @@ let loadedUnusedEntities = false; declare global { // tslint:disable-next-line interface HASSDomEvents { - opened: {}; + opened: { value: boolean }; } } From 56c1920cc167b3c15d7ca734e52676571ab7f98d Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Thu, 14 Feb 2019 23:16:09 -0600 Subject: [PATCH 04/18] css is dumb --- package.json | 1 - .../notifications/hui-notifications-button.ts | 26 +++++++++++++++---- yarn.lock | 11 -------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index f986dc0baa..29f016bb22 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "@polymer/iron-pages": "^3.0.1", "@polymer/iron-resizable-behavior": "^3.0.1", "@polymer/neon-animation": "^3.0.1", - "@polymer/paper-badge": "^3.0.1", "@polymer/paper-button": "^3.0.1", "@polymer/paper-card": "^3.0.1", "@polymer/paper-checkbox": "^3.0.1", diff --git a/src/panels/lovelace/components/notifications/hui-notifications-button.ts b/src/panels/lovelace/components/notifications/hui-notifications-button.ts index 169c1cc4c1..8d72ef1623 100644 --- a/src/panels/lovelace/components/notifications/hui-notifications-button.ts +++ b/src/panels/lovelace/components/notifications/hui-notifications-button.ts @@ -6,7 +6,6 @@ import { CSSResult, property, } from "lit-element"; -import "@polymer/paper-badge/paper-badge"; import "@polymer/paper-icon-button/paper-icon-button"; import { fireEvent } from "../../../../common/dom/fire_event"; @@ -22,7 +21,9 @@ class HuiNotificationsButton extends LitElement { > ${this.notifications ? html` - + +
${this.notifications.length}
+
` : ""} `; @@ -34,9 +35,24 @@ class HuiNotificationsButton extends LitElement { :host { position: relative; } - paper-badge { - left: 23px !important; - top: 0px !important; + + .indicator { + position: absolute; + top: 0px; + right: -3px; + width: 20px; + height: 20px; + border-radius: 50%; + background: var(--accent-color); + pointer-events: none; + z-index: 1; + } + + .indicator > div { + right: 7px; + top: 3px; + position: absolute; + font-size: 0.55em; } `, ]; diff --git a/yarn.lock b/yarn.lock index 4a19d56968..318b196f2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1148,17 +1148,6 @@ "@polymer/iron-selector" "^3.0.0-pre.26" "@polymer/polymer" "^3.0.0" -"@polymer/paper-badge@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@polymer/paper-badge/-/paper-badge-3.0.1.tgz#ea973090342c66f99ea6ef1d32fc534ee40630e8" - integrity sha512-9lHB/AFPuDAY/+OPNio1Mi6JUAM8yQqzJEAkk99IwcCl9VB6uCjlrXVfistrYIv7z+Wy4SZHNEtA6xR1+FhCDg== - dependencies: - "@polymer/iron-flex-layout" "^3.0.0-pre.26" - "@polymer/iron-icon" "^3.0.0-pre.26" - "@polymer/iron-resizable-behavior" "^3.0.0-pre.26" - "@polymer/paper-styles" "^3.0.0-pre.26" - "@polymer/polymer" "^3.0.0" - "@polymer/paper-behaviors@^3.0.0-pre.27": version "3.0.1" resolved "https://registry.yarnpkg.com/@polymer/paper-behaviors/-/paper-behaviors-3.0.1.tgz#83f1cd06489f484c1b108a2967fb01952df722ad" From 34f36c617992f250e78915791dc4e96ddd4a7af1 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 15 Feb 2019 08:49:48 -0800 Subject: [PATCH 05/18] Update package.json --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 29f016bb22..4577c34aed 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "@polymer/iron-pages": "^3.0.1", "@polymer/iron-resizable-behavior": "^3.0.1", "@polymer/neon-animation": "^3.0.1", - "@polymer/paper-button": "^3.0.1", "@polymer/paper-card": "^3.0.1", "@polymer/paper-checkbox": "^3.0.1", "@polymer/paper-dialog": "^3.0.1", From bdaf96b1146811b2b9311d036e84850585038222 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Sat, 16 Feb 2019 13:31:41 -0600 Subject: [PATCH 06/18] address review comments --- .../components/notifications/hui-notifications-button.ts | 2 +- src/panels/lovelace/hui-root.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/components/notifications/hui-notifications-button.ts b/src/panels/lovelace/components/notifications/hui-notifications-button.ts index 8d72ef1623..f58f3425aa 100644 --- a/src/panels/lovelace/components/notifications/hui-notifications-button.ts +++ b/src/panels/lovelace/components/notifications/hui-notifications-button.ts @@ -60,7 +60,7 @@ class HuiNotificationsButton extends LitElement { private _clicked() { this.opened = true; - fireEvent(this, "opened", { value: this.opened }); + fireEvent(this, "opened-changed", { value: this.opened }); } } diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index f5398d139c..718d34a176 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -194,7 +194,7 @@ class HUIRoot extends LitElement { Date: Sat, 16 Feb 2019 13:57:39 -0600 Subject: [PATCH 07/18] lint --- src/panels/lovelace/hui-root.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 718d34a176..a7da02aca9 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -60,7 +60,7 @@ let loadedUnusedEntities = false; declare global { // tslint:disable-next-line interface HASSDomEvents { - opened: { value: boolean }; + "opened-changed": { value: boolean }; } } From da80bfa3c7826fca75417d0b413e3a57abcce638 Mon Sep 17 00:00:00 2001 From: Jason Hu Date: Sat, 16 Feb 2019 23:35:10 -0800 Subject: [PATCH 08/18] Change recommend VSCode TSLint plugin to offical supported one (#2775) --- .vscode/extensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 207b186d35..411ffee836 100755 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,7 @@ { "recommendations": [ "dbaeumer.vscode-eslint", - "eg2.tslint", + "ms-vscode.vscode-typescript-tslint-plugin", "esbenp.prettier-vscode", "bierner.lit-html", "runem.lit-plugin" From 3b008b63597ad84526ca00748241fd273b541f19 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 17 Feb 2019 09:06:50 -0800 Subject: [PATCH 09/18] Revoke old camera image after new one has loaded (#2772) --- src/panels/lovelace/components/hui-image.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/panels/lovelace/components/hui-image.ts b/src/panels/lovelace/components/hui-image.ts index cdc7b06aa1..04a12f34d8 100644 --- a/src/panels/lovelace/components/hui-image.ts +++ b/src/panels/lovelace/components/hui-image.ts @@ -167,15 +167,14 @@ class HuiImage extends LitElement { if (!this.hass || !this.cameraImage) { return; } - if (this._cameraImageSrc) { - URL.revokeObjectURL(this._cameraImageSrc); - this._cameraImageSrc = undefined; - } try { const { content_type: contentType, content } = await fetchThumbnail( this.hass, this.cameraImage ); + if (this._cameraImageSrc) { + URL.revokeObjectURL(this._cameraImageSrc); + } this._cameraImageSrc = URL.createObjectURL( b64toBlob(content, contentType) ); From b6b224be77ae9918be74a6f43c8fde049305e0b1 Mon Sep 17 00:00:00 2001 From: Jason Hu Date: Sun, 17 Feb 2019 10:48:03 -0800 Subject: [PATCH 10/18] Fix user initial in sidebar (#2777) --- src/components/ha-sidebar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts index 82cf0585ab..6e6d5fc658 100644 --- a/src/components/ha-sidebar.ts +++ b/src/components/ha-sidebar.ts @@ -83,7 +83,7 @@ class HaSidebar extends LitElement { ${hass.user ? html` - + ` : ""} From 7d8f79070833120e7e081a4bcdcd914e20a3327e Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Sun, 17 Feb 2019 22:00:21 -0600 Subject: [PATCH 11/18] fix for thermostat reporting null target temp (#2730) * fix for thermostat reporting null target temp * address review comments --- src/panels/lovelace/cards/hui-thermostat-card.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 8ddd773838..704b34b080 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -280,7 +280,10 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { ); } else { sliderValue = stateObj.attributes.temperature; - uiValue = "" + stateObj.attributes.temperature; + uiValue = + stateObj.attributes.temperature !== null + ? String(stateObj.attributes.temperature) + : ""; } return [sliderValue, uiValue]; From 5e6b28d965c2b6444095297a1d99df823782edbb Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Sun, 17 Feb 2019 22:17:45 -0600 Subject: [PATCH 12/18] address review comments --- .../components/notifications/hui-notifications-button.ts | 9 ++++++++- src/panels/lovelace/hui-root.ts | 7 ------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/panels/lovelace/components/notifications/hui-notifications-button.ts b/src/panels/lovelace/components/notifications/hui-notifications-button.ts index f58f3425aa..c56d2931a1 100644 --- a/src/panels/lovelace/components/notifications/hui-notifications-button.ts +++ b/src/panels/lovelace/components/notifications/hui-notifications-button.ts @@ -9,6 +9,13 @@ import { import "@polymer/paper-icon-button/paper-icon-button"; import { fireEvent } from "../../../../common/dom/fire_event"; +declare global { + // tslint:disable-next-line + interface HASSDomEvents { + "opened-changed": { value: boolean }; + } +} + class HuiNotificationsButton extends LitElement { @property() public notifications?: string[]; @property() public opened?: boolean; @@ -19,7 +26,7 @@ class HuiNotificationsButton extends LitElement { icon="hass:bell" @click="${this._clicked}" > - ${this.notifications + ${this.notifications && this.notifications.length > 0 ? html`
${this.notifications.length}
diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index a7da02aca9..e2973b7573 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -57,13 +57,6 @@ const JS_CACHE = {}; let loadedUnusedEntities = false; -declare global { - // tslint:disable-next-line - interface HASSDomEvents { - "opened-changed": { value: boolean }; - } -} - class HUIRoot extends LitElement { public narrow?: boolean; public showMenu?: boolean; From a4ec8719f97322d63c29ea26372cd5455122ec68 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Sun, 17 Feb 2019 22:43:46 -0600 Subject: [PATCH 13/18] warning when light unavilable (#2771) * error-card when light unavilable * single warning element for all * address review comments * address review comments --- .../lovelace/cards/hui-alarm-panel-card.ts | 16 +- src/panels/lovelace/cards/hui-gauge-card.ts | 273 +++++++++--------- src/panels/lovelace/cards/hui-light-card.ts | 74 ++--- .../lovelace/cards/hui-picture-entity-card.ts | 18 +- .../lovelace/cards/hui-thermostat-card.ts | 21 +- src/panels/lovelace/components/hui-warning.ts | 34 +++ .../entity-rows/hui-climate-entity-row.ts | 44 +-- .../entity-rows/hui-cover-entity-row.ts | 42 ++- .../entity-rows/hui-error-entity-row.ts | 41 --- .../entity-rows/hui-group-entity-row.ts | 30 +- .../hui-input-select-entity-row.ts | 50 ++-- .../entity-rows/hui-input-text-entity-row.ts | 30 +- .../entity-rows/hui-lock-entity-row.ts | 42 ++- .../hui-media-player-entity-row.ts | 44 +-- .../entity-rows/hui-scene-entity-row.ts | 44 ++- .../entity-rows/hui-script-entity-row.ts | 44 ++- .../entity-rows/hui-sensor-entity-row.ts | 40 ++- .../entity-rows/hui-text-entity-row.ts | 40 ++- .../entity-rows/hui-toggle-entity-row.ts | 12 +- src/translations/en.json | 4 + 20 files changed, 446 insertions(+), 497 deletions(-) create mode 100644 src/panels/lovelace/components/hui-warning.ts delete mode 100644 src/panels/lovelace/entity-rows/hui-error-entity-row.ts diff --git a/src/panels/lovelace/cards/hui-alarm-panel-card.ts b/src/panels/lovelace/cards/hui-alarm-panel-card.ts index 3fb008f6c3..f6cc8e92d1 100644 --- a/src/panels/lovelace/cards/hui-alarm-panel-card.ts +++ b/src/panels/lovelace/cards/hui-alarm-panel-card.ts @@ -19,10 +19,7 @@ import { import "../../../components/ha-card"; import "../../../components/ha-label-badge"; -import { - createErrorCardConfig, - createErrorCardElement, -} from "./hui-error-card"; +import "../components/hui-warning"; const ICONS = { armed_away: "hass:shield-lock", @@ -107,11 +104,14 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard { const stateObj = this.hass.states[this._config.entity]; if (!stateObj) { - const element = createErrorCardElement( - createErrorCardConfig("Entity not Found!", this._config) - ); return html` - ${element} + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } diff --git a/src/panels/lovelace/cards/hui-gauge-card.ts b/src/panels/lovelace/cards/hui-gauge-card.ts index 0638e01b54..79ffa484f5 100644 --- a/src/panels/lovelace/cards/hui-gauge-card.ts +++ b/src/panels/lovelace/cards/hui-gauge-card.ts @@ -1,27 +1,27 @@ import { html, LitElement, - PropertyDeclarations, PropertyValues, TemplateResult, + css, + CSSResult, + property, } from "lit-element"; import { styleMap } from "lit-html/directives/style-map"; import "../../../components/ha-card"; +import "../components/hui-warning"; + import { LovelaceCardConfig } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { fireEvent } from "../../../common/dom/fire_event"; import { hasConfigOrEntityChanged } from "../common/has-changed"; +import { LovelaceCard, LovelaceCardEditor } from "../types"; + import isValidEntityId from "../../../common/entity/valid_entity_id"; import applyThemesOnElement from "../../../common/dom/apply_themes_on_element"; import computeStateName from "../../../common/entity/compute_state_name"; -import { LovelaceCard, LovelaceCardEditor } from "../types"; -import { - createErrorCardConfig, - createErrorCardElement, -} from "./hui-error-card"; - export interface SeverityConfig { green?: number; yellow?: number; @@ -54,17 +54,10 @@ class HuiGaugeCard extends LitElement implements LovelaceCard { return {}; } - public hass?: HomeAssistant; - private _config?: Config; + @property() public hass?: HomeAssistant; + @property() private _config?: Config; private _updated?: boolean; - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } - public getCardSize(): number { return 2; } @@ -88,57 +81,59 @@ class HuiGaugeCard extends LitElement implements LovelaceCard { if (!this._config || !this.hass) { return html``; } + const stateObj = this.hass.states[this._config.entity]; - let state; - let error; if (!stateObj) { - error = "Entity not available: " + this._config.entity; - } else { - state = Number(stateObj.state); - - if (isNaN(state)) { - error = "Entity is non-numeric: " + this._config.entity; - } + return html` + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} + `; } - if (error) { + const state = Number(stateObj.state); + + if (isNaN(state)) { return html` - ${createErrorCardElement(createErrorCardConfig(error, this._config))} + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_non_numeric", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()} - ${error - ? html` -
${error}
- ` - : html` -
-
-
-
-
-
- ${stateObj.state} - ${this._config.unit || - stateObj.attributes.unit_of_measurement || - ""} -
-
- ${this._config.name || computeStateName(stateObj)} -
-
-
- `} +
+
+
+
+
+
+ ${stateObj.state} + ${this._config.unit || + stateObj.attributes.unit_of_measurement || + ""} +
+
+ ${this._config.name || computeStateName(stateObj)} +
+
+
`; } @@ -225,90 +220,88 @@ class HuiGaugeCard extends LitElement implements LovelaceCard { fireEvent(this, "hass-more-info", { entityId: this._config!.entity }); } - private renderStyle(): TemplateResult { - return html` - + static get styles(): CSSResult { + return css` + ha-card { + --base-unit: 50px; + height: calc(var(--base-unit) * 3); + position: relative; + cursor: pointer; + } + .container { + width: calc(var(--base-unit) * 4); + height: calc(var(--base-unit) * 2); + position: absolute; + top: calc(var(--base-unit) * 1.5); + left: 50%; + overflow: hidden; + text-align: center; + transform: translate(-50%, -50%); + } + .gauge-a { + z-index: 1; + position: absolute; + background-color: var(--primary-background-color); + width: calc(var(--base-unit) * 4); + height: calc(var(--base-unit) * 2); + top: 0%; + border-radius: calc(var(--base-unit) * 2.5) calc(var(--base-unit) * 2.5) + 0px 0px; + } + .gauge-b { + z-index: 3; + position: absolute; + background-color: var(--paper-card-background-color); + width: calc(var(--base-unit) * 2.5); + height: calc(var(--base-unit) * 1.25); + top: calc(var(--base-unit) * 0.75); + margin-left: calc(var(--base-unit) * 0.75); + margin-right: auto; + border-radius: calc(var(--base-unit) * 2.5) calc(var(--base-unit) * 2.5) + 0px 0px; + } + .gauge-c { + z-index: 2; + position: absolute; + background-color: var(--label-badge-blue); + width: calc(var(--base-unit) * 4); + height: calc(var(--base-unit) * 2); + top: calc(var(--base-unit) * 2); + margin-left: auto; + margin-right: auto; + border-radius: 0px 0px calc(var(--base-unit) * 2) + calc(var(--base-unit) * 2); + transform-origin: center top; + } + .init .gauge-c { + transition: all 1.3s ease-in-out; + } + .gauge-data { + z-index: 4; + color: var(--primary-text-color); + line-height: calc(var(--base-unit) * 0.3); + position: absolute; + width: calc(var(--base-unit) * 4); + height: calc(var(--base-unit) * 2.1); + top: calc(var(--base-unit) * 1.2); + margin-left: auto; + margin-right: auto; + } + .init .gauge-data { + transition: all 1s ease-out; + } + .gauge-data #percent { + font-size: calc(var(--base-unit) * 0.55); + } + .gauge-data #name { + padding-top: calc(var(--base-unit) * 0.15); + font-size: calc(var(--base-unit) * 0.3); + } + .not-found { + flex: 1; + background-color: yellow; + padding: 8px; + } `; } } diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index 785eb339e2..7e30776ef1 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -22,6 +22,7 @@ import applyThemesOnElement from "../../../common/dom/apply_themes_on_element"; import "../../../components/ha-card"; import "../../../components/ha-icon"; +import "../components/hui-warning"; const lightConfig = { radius: 80, @@ -78,41 +79,45 @@ export class HuiLightCard extends LitElement implements LovelaceCard { const stateObj = this.hass.states[this._config!.entity] as LightEntity; + if (!stateObj) { + return html` + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} + `; + } + return html` ${this.renderStyle()} - ${!stateObj - ? html` -
- Entity not available: ${this._config.entity} -
- ` - : html` - -
-
-
- -
-
- ${this._config.name || computeStateName(stateObj)} -
-
-
- `} + +
+
+
+ +
+
+ ${this._config.name || computeStateName(stateObj)} +
+
+
`; } @@ -272,11 +277,6 @@ export class HuiLightCard extends LitElement implements LovelaceCard { .show_brightness { opacity: 1; } - .not-found { - flex: 1; - background-color: yellow; - padding: 8px; - } .more-info { position: absolute; cursor: pointer; diff --git a/src/panels/lovelace/cards/hui-picture-entity-card.ts b/src/panels/lovelace/cards/hui-picture-entity-card.ts index b3a20c9523..9fa618a6a0 100644 --- a/src/panels/lovelace/cards/hui-picture-entity-card.ts +++ b/src/panels/lovelace/cards/hui-picture-entity-card.ts @@ -8,6 +8,7 @@ import { classMap } from "lit-html/directives/class-map"; import "../../../components/ha-card"; import "../components/hui-image"; +import "../components/hui-warning"; import computeDomain from "../../../common/entity/compute_domain"; import computeStateDisplay from "../../../common/entity/compute_state_display"; @@ -19,10 +20,6 @@ import { LovelaceCardConfig, ActionConfig } from "../../../data/lovelace"; import { LovelaceCard } from "../types"; import { handleClick } from "../common/handle-click"; import { UNAVAILABLE } from "../../../data/entity"; -import { - createErrorCardElement, - createErrorCardConfig, -} from "./hui-error-card"; interface Config extends LovelaceCardConfig { entity: string; @@ -76,12 +73,13 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard { if (!stateObj) { return html` - ${createErrorCardElement( - createErrorCardConfig( - `Entity not found: ${this._config.entity}`, - this._config - ) - )} + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 704b34b080..21c5d70614 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -10,6 +10,7 @@ import "@polymer/paper-icon-button/paper-icon-button"; import "../../../components/ha-card"; import "../../../components/ha-icon"; +import "../components/hui-warning"; import applyThemesOnElement from "../../../common/dom/apply_themes_on_element"; import computeStateName from "../../../common/entity/compute_state_name"; @@ -102,16 +103,19 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { return html``; } const stateObj = this.hass.states[this._config.entity] as ClimateEntity; + if (!stateObj) { return html` - ${this.renderStyle()} - -
- Entity not available: ${this._config.entity} -
-
+ ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } + const mode = modeIcons[stateObj.attributes.operation_mode || ""] ? stateObj.attributes.operation_mode! : "unknown-mode"; @@ -387,11 +391,6 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { --idle-color: #8a8a8a; --unknown-color: #bac; } - .not-found { - flex: 1; - background-color: yellow; - padding: 8px; - } #root { position: relative; overflow: hidden; diff --git a/src/panels/lovelace/components/hui-warning.ts b/src/panels/lovelace/components/hui-warning.ts new file mode 100644 index 0000000000..7bbbe1af67 --- /dev/null +++ b/src/panels/lovelace/components/hui-warning.ts @@ -0,0 +1,34 @@ +import { + html, + LitElement, + TemplateResult, + CSSResult, + css, + customElement, +} from "lit-element"; + +@customElement("hui-warning") +export class HuiWarning extends LitElement { + protected render(): TemplateResult | void { + return html` + + `; + } + + static get styles(): CSSResult { + return css` + :host { + display: block; + color: black; + background-color: #fce588; + padding: 8px; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-warning": HuiWarning; + } +} diff --git a/src/panels/lovelace/entity-rows/hui-climate-entity-row.ts b/src/panels/lovelace/entity-rows/hui-climate-entity-row.ts index d452445d78..9487294b76 100644 --- a/src/panels/lovelace/entity-rows/hui-climate-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-climate-entity-row.ts @@ -1,21 +1,22 @@ -import { html, LitElement, TemplateResult } from "lit-element"; +import { + html, + LitElement, + TemplateResult, + property, + css, + CSSResult, +} from "lit-element"; import "../../../components/ha-climate-state"; import "../components/hui-generic-entity-row"; +import "../components/hui-warning"; import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; class HuiClimateEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties() { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config || !config.entity) { @@ -34,14 +35,17 @@ class HuiClimateEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()} - ha-climate-state { - text-align: right; - } - + static get styles(): CSSResult { + return css` + ha-climate-state { + text-align: right; + } `; } } diff --git a/src/panels/lovelace/entity-rows/hui-cover-entity-row.ts b/src/panels/lovelace/entity-rows/hui-cover-entity-row.ts index 2920416d91..148c1614c2 100644 --- a/src/panels/lovelace/entity-rows/hui-cover-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-cover-entity-row.ts @@ -1,29 +1,24 @@ import { html, LitElement, - PropertyDeclarations, TemplateResult, + property, + css, + CSSResult, } from "lit-element"; import "../components/hui-generic-entity-row"; import "../../../components/ha-cover-controls"; import "../../../components/ha-cover-tilt-controls"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import { isTiltOnly } from "../../../util/cover-model"; import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; class HuiCoverEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config) { @@ -41,14 +36,17 @@ class HuiCoverEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()} ${isTiltOnly(stateObj) ? html` @@ -67,14 +65,12 @@ class HuiCoverEntityRow extends LitElement implements EntityRow { `; } - private renderStyle(): TemplateResult { - return html` - + static get styles(): CSSResult { + return css` + ha-cover-controls, + ha-cover-tilt-controls { + margin-right: -0.57em; + } `; } } diff --git a/src/panels/lovelace/entity-rows/hui-error-entity-row.ts b/src/panels/lovelace/entity-rows/hui-error-entity-row.ts deleted file mode 100644 index fc0265eddb..0000000000 --- a/src/panels/lovelace/entity-rows/hui-error-entity-row.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { html, LitElement, TemplateResult } from "lit-element"; - -class HuiErrorEntityRow extends LitElement { - public entity?: string; - public error?: string; - - static get properties() { - return { - error: {}, - entity: {}, - }; - } - - protected render(): TemplateResult | void { - return html` - ${this.renderStyle()} ${this.error || "Entity not available"}: - ${this.entity || ""} - `; - } - - private renderStyle(): TemplateResult { - return html` - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - "hui-error-entity-row": HuiErrorEntityRow; - } -} - -customElements.define("hui-error-entity-row", HuiErrorEntityRow); diff --git a/src/panels/lovelace/entity-rows/hui-group-entity-row.ts b/src/panels/lovelace/entity-rows/hui-group-entity-row.ts index e8afa8acc6..e422037ca6 100644 --- a/src/panels/lovelace/entity-rows/hui-group-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-group-entity-row.ts @@ -1,13 +1,8 @@ -import { - html, - LitElement, - PropertyDeclarations, - TemplateResult, -} from "lit-element"; +import { html, LitElement, TemplateResult, property } from "lit-element"; import "../components/hui-generic-entity-row"; import "../../../components/entity/ha-entity-toggle"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import computeStateDisplay from "../../../common/entity/compute_state_display"; import { DOMAINS_TOGGLE } from "../../../common/const"; @@ -15,15 +10,8 @@ import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; class HuiGroupEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config) { @@ -41,9 +29,13 @@ class HuiGroupEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } diff --git a/src/panels/lovelace/entity-rows/hui-input-select-entity-row.ts b/src/panels/lovelace/entity-rows/hui-input-select-entity-row.ts index 2ee0010b2b..77c056524c 100644 --- a/src/panels/lovelace/entity-rows/hui-input-select-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-input-select-entity-row.ts @@ -1,8 +1,10 @@ import { html, LitElement, - PropertyDeclarations, TemplateResult, + property, + css, + CSSResult, } from "lit-element"; import { repeat } from "lit-html/directives/repeat"; import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; @@ -10,7 +12,7 @@ import "@polymer/paper-item/paper-item"; import "@polymer/paper-listbox/paper-listbox"; import "../../../components/entity/state-badge"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import computeStateName from "../../../common/entity/compute_state_name"; import { HomeAssistant } from "../../../types"; @@ -18,15 +20,8 @@ import { EntityRow, EntityConfig } from "./types"; import { setOption } from "../../../data/input-select"; class HuiInputSelectEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config || !config.entity) { @@ -45,14 +40,17 @@ class HuiInputSelectEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()} - :host { - display: flex; - align-items: center; - } - paper-dropdown-menu { - margin-left: 16px; - flex: 1; - } - + static get styles(): CSSResult { + return css` + :host { + display: flex; + align-items: center; + } + paper-dropdown-menu { + margin-left: 16px; + flex: 1; + } `; } diff --git a/src/panels/lovelace/entity-rows/hui-input-text-entity-row.ts b/src/panels/lovelace/entity-rows/hui-input-text-entity-row.ts index 9aae5b482d..1456bb9492 100644 --- a/src/panels/lovelace/entity-rows/hui-input-text-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-input-text-entity-row.ts @@ -1,28 +1,16 @@ -import { - html, - LitElement, - PropertyDeclarations, - TemplateResult, -} from "lit-element"; +import { html, LitElement, TemplateResult, property } from "lit-element"; import { PaperInputElement } from "@polymer/paper-input/paper-input"; import "../components/hui-generic-entity-row"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; import { setValue } from "../../../data/input_text"; class HuiInputTextEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config) { @@ -40,9 +28,13 @@ class HuiInputTextEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } diff --git a/src/panels/lovelace/entity-rows/hui-lock-entity-row.ts b/src/panels/lovelace/entity-rows/hui-lock-entity-row.ts index 420185b4d8..15c0acbf5c 100644 --- a/src/panels/lovelace/entity-rows/hui-lock-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-lock-entity-row.ts @@ -1,26 +1,21 @@ import { html, LitElement, - PropertyDeclarations, TemplateResult, + property, + css, + CSSResult, } from "lit-element"; import "../components/hui-generic-entity-row"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; class HuiLockEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config) { @@ -38,14 +33,17 @@ class HuiLockEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()} ${stateObj.state === "locked" @@ -56,15 +54,11 @@ class HuiLockEntityRow extends LitElement implements EntityRow { `; } - protected renderStyle(): TemplateResult { - return html` - + static get styles(): CSSResult { + return css` + mwc-button { + margin-right: -0.57em; + } `; } diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts index 12e419828e..3defa48446 100644 --- a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts @@ -1,7 +1,15 @@ -import { html, LitElement, TemplateResult } from "lit-element"; +import { + html, + LitElement, + TemplateResult, + css, + CSSResult, + property, +} from "lit-element"; import "@polymer/paper-icon-button/paper-icon-button"; import "../components/hui-generic-entity-row"; +import "../components/hui-warning"; import { EntityRow, EntityConfig } from "./types"; import { HomeAssistant } from "../../../types"; @@ -15,15 +23,8 @@ import { } from "../../../data/media-player"; class HuiMediaPlayerEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties() { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config || !config.entity) { @@ -42,14 +43,17 @@ class HuiMediaPlayerEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()} - .controls { - white-space: nowrap; - } - + static get styles(): CSSResult { + return css` + .controls { + white-space: nowrap; + } `; } diff --git a/src/panels/lovelace/entity-rows/hui-scene-entity-row.ts b/src/panels/lovelace/entity-rows/hui-scene-entity-row.ts index 045dba7df9..c26f0e7deb 100644 --- a/src/panels/lovelace/entity-rows/hui-scene-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-scene-entity-row.ts @@ -1,27 +1,22 @@ import { html, LitElement, - PropertyDeclarations, TemplateResult, + CSSResult, + css, + property, } from "lit-element"; import "../components/hui-generic-entity-row"; import "../../../components/entity/ha-entity-toggle"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; class HuiSceneEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config) { @@ -39,14 +34,17 @@ class HuiSceneEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()} ${stateObj.attributes.can_cancel ? html` @@ -64,15 +62,13 @@ class HuiSceneEntityRow extends LitElement implements EntityRow { `; } - protected renderStyle(): TemplateResult { - return html` - + static get styles(): CSSResult { + return css` + mwc-button { + color: var(--primary-color); + font-weight: 500; + margin-right: -0.57em; + } `; } diff --git a/src/panels/lovelace/entity-rows/hui-script-entity-row.ts b/src/panels/lovelace/entity-rows/hui-script-entity-row.ts index 3a31251d14..16c8ab7fda 100644 --- a/src/panels/lovelace/entity-rows/hui-script-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-script-entity-row.ts @@ -1,27 +1,22 @@ import { html, LitElement, - PropertyDeclarations, TemplateResult, + property, + CSSResult, + css, } from "lit-element"; import "../components/hui-generic-entity-row"; import "../../../components/entity/ha-entity-toggle"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; class HuiScriptEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config) { @@ -39,14 +34,17 @@ class HuiScriptEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()} ${stateObj.attributes.can_cancel ? html` @@ -64,15 +62,13 @@ class HuiScriptEntityRow extends LitElement implements EntityRow { `; } - protected renderStyle(): TemplateResult { - return html` - + static get styles(): CSSResult { + return css` + mwc-button { + color: var(--primary-color); + font-weight: 500; + margin-right: -0.57em; + } `; } diff --git a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts index ac4a261a55..4c65f99cf0 100644 --- a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts @@ -1,13 +1,15 @@ import { html, LitElement, - PropertyDeclarations, TemplateResult, + property, + CSSResult, + css, } from "lit-element"; import "../components/hui-generic-entity-row"; import "../components/hui-timestamp-display"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; @@ -19,15 +21,8 @@ interface SensorEntityConfig extends EntityConfig { } class HuiSensorEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: SensorEntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: SensorEntityConfig; public setConfig(config: SensorEntityConfig): void { if (!config) { @@ -45,14 +40,17 @@ class HuiSensorEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()}
${stateObj.attributes.device_class === "timestamp" @@ -73,13 +71,11 @@ class HuiSensorEntityRow extends LitElement implements EntityRow { `; } - private renderStyle(): TemplateResult { - return html` - + static get styles(): CSSResult { + return css` + div { + text-align: right; + } `; } } diff --git a/src/panels/lovelace/entity-rows/hui-text-entity-row.ts b/src/panels/lovelace/entity-rows/hui-text-entity-row.ts index e30bdf27e5..5fd9f2f442 100644 --- a/src/panels/lovelace/entity-rows/hui-text-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-text-entity-row.ts @@ -1,27 +1,22 @@ import { html, LitElement, - PropertyDeclarations, TemplateResult, + property, + CSSResult, + css, } from "lit-element"; import "../components/hui-generic-entity-row"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import computeStateDisplay from "../../../common/entity/compute_state_display"; import { HomeAssistant } from "../../../types"; import { EntityRow, EntityConfig } from "./types"; class HuiTextEntityRow extends LitElement implements EntityRow { - public hass?: HomeAssistant; - private _config?: EntityConfig; - - static get properties(): PropertyDeclarations { - return { - hass: {}, - _config: {}, - }; - } + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; public setConfig(config: EntityConfig): void { if (!config) { @@ -39,14 +34,17 @@ class HuiTextEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } return html` - ${this.renderStyle()}
${computeStateDisplay( @@ -59,13 +57,11 @@ class HuiTextEntityRow extends LitElement implements EntityRow { `; } - private renderStyle(): TemplateResult { - return html` - + static get styles(): CSSResult { + return css` + div { + text-align: right; + } `; } } diff --git a/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts b/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts index f5a7848835..e91a47e460 100644 --- a/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts @@ -7,7 +7,7 @@ import { import "../components/hui-generic-entity-row"; import "../../../components/entity/ha-entity-toggle"; -import "./hui-error-entity-row"; +import "../components/hui-warning"; import computeStateDisplay from "../../../common/entity/compute_state_display"; import { HomeAssistant } from "../../../types"; @@ -40,9 +40,13 @@ class HuiToggleEntityRow extends LitElement implements EntityRow { if (!stateObj) { return html` - + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this._config.entity + )} `; } diff --git a/src/translations/en.json b/src/translations/en.json index 051b352259..35207ed514 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -899,6 +899,10 @@ "para_migrate": "Home Assistant can add ID's to all your cards and views automatically for you by pressing the 'Migrate config' button.", "migrate": "Migrate config" } + }, + "warning": { + "entity_not_found": "Entity not available: {entity}", + "entity_non_numeric": "Entity is non-numeric: {entity}" } }, "mailbox": { From 2ada32be02e75b24ea1c580494cfa450636a65df Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Mon, 18 Feb 2019 00:44:01 -0600 Subject: [PATCH 14/18] Cleanup mwc-button css (#2780) ``font-weight: 500;` `color: var(--primary-color);` are not necessary to specify --- src/cards/ha-persistent_notification-card.js | 1 - src/components/ha-vacuum-state.js | 2 -- .../more-info/controls/more-info-alarm_control_panel.js | 1 - src/dialogs/more-info/controls/more-info-automation.js | 4 ---- src/panels/config/cloud/cloud-webhook-manage-dialog.ts | 4 ---- src/panels/config/cloud/cloud-webhooks.ts | 4 ---- src/panels/config/cloud/ha-config-cloud-account.js | 4 ---- .../config/config-entries/ha-config-entries-dashboard.js | 2 -- src/panels/lovelace/cards/hui-alarm-panel-card.ts | 1 - src/panels/lovelace/cards/hui-empty-state-card.ts | 2 -- src/panels/lovelace/entity-rows/hui-scene-entity-row.ts | 2 -- src/panels/lovelace/entity-rows/hui-script-entity-row.ts | 2 -- src/panels/lovelace/ha-panel-lovelace.ts | 6 ------ src/panels/lovelace/special-rows/hui-call-service-row.ts | 2 -- src/panels/profile/ha-mfa-modules-card.js | 2 -- src/state-summary/state-card-configurator.js | 2 -- src/state-summary/state-card-lock.js | 2 -- src/state-summary/state-card-scene.js | 2 -- src/state-summary/state-card-script.js | 2 -- 19 files changed, 47 deletions(-) diff --git a/src/cards/ha-persistent_notification-card.js b/src/cards/ha-persistent_notification-card.js index bea39bbf97..95cf52845f 100644 --- a/src/cards/ha-persistent_notification-card.js +++ b/src/cards/ha-persistent_notification-card.js @@ -40,7 +40,6 @@ class HaPersistentNotificationCard extends LocalizeMixin(PolymerElement) { } mwc-button { margin: 8px; - font-weight: 500; } diff --git a/src/components/ha-vacuum-state.js b/src/components/ha-vacuum-state.js index 5dc82224dd..556dac2619 100644 --- a/src/components/ha-vacuum-state.js +++ b/src/components/ha-vacuum-state.js @@ -39,8 +39,6 @@ class HaVacuumState extends LocalizeMixin(PolymerElement) { return html`
diff --git a/src/panels/config/config-entries/ha-config-entries-dashboard.js b/src/panels/config/config-entries/ha-config-entries-dashboard.js index c89e5f3b7f..276e8eb74e 100644 --- a/src/panels/config/config-entries/ha-config-entries-dashboard.js +++ b/src/panels/config/config-entries/ha-config-entries-dashboard.js @@ -30,8 +30,6 @@ class HaConfigManagerDashboard extends LocalizeMixin( return html` diff --git a/src/panels/profile/ha-mfa-modules-card.js b/src/panels/profile/ha-mfa-modules-card.js index bae240bbf5..f791f200ef 100644 --- a/src/panels/profile/ha-mfa-modules-card.js +++ b/src/panels/profile/ha-mfa-modules-card.js @@ -37,8 +37,6 @@ class HaMfaModulesCard extends EventsMixin(LocalizeMixin(PolymerElement)) { margin: 16px auto; } mwc-button { - color: var(--primary-color); - font-weight: 500; margin-right: -0.57em; } diff --git a/src/state-summary/state-card-configurator.js b/src/state-summary/state-card-configurator.js index daacf85736..5cc66cf4f5 100644 --- a/src/state-summary/state-card-configurator.js +++ b/src/state-summary/state-card-configurator.js @@ -16,8 +16,6 @@ class StateCardConfigurator extends LocalizeMixin(PolymerElement) { `; } @@ -189,10 +186,13 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard { if (!stateObj) { return html` -
-
${entityConf.entity}
- Entity Not Available -
+ ${this.hass!.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + entityConf.entity + )} `; } diff --git a/src/panels/lovelace/cards/hui-sensor-card.ts b/src/panels/lovelace/cards/hui-sensor-card.ts index 6bc8630dcf..8dbdab4fea 100644 --- a/src/panels/lovelace/cards/hui-sensor-card.ts +++ b/src/panels/lovelace/cards/hui-sensor-card.ts @@ -12,6 +12,7 @@ import { LovelaceCard, LovelaceCardEditor } from "../types"; import { LovelaceCardConfig } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { fireEvent } from "../../../common/dom/fire_event"; +import { fetchRecent } from "../../../data/history"; import applyThemesOnElement from "../../../common/dom/apply_themes_on_element"; import computeStateName from "../../../common/entity/compute_state_name"; @@ -19,7 +20,7 @@ import stateIcon from "../../../common/entity/state_icon"; import "../../../components/ha-card"; import "../../../components/ha-icon"; -import { fetchRecent } from "../../../data/history"; +import "../components/hui-warning"; const midPoint = ( _Ax: number, @@ -199,15 +200,27 @@ class HuiSensorCard extends LitElement implements LovelaceCard { 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 + )} + `; + } + let graph; if (stateObj && this._config.graph === "line") { if (!stateObj.attributes.unit_of_measurement) { - graph = html` -
- Entity: ${this._config.entity} - Has no Unit of Measurement and - therefore can not display a line graph. -
+ return html` + Entity: ${this._config.entity} - Has no Unit of Measurement and + therefore can not display a line graph. `; } else if (!this._history) { graph = svg` @@ -233,34 +246,26 @@ class HuiSensorCard extends LitElement implements LovelaceCard { return html` ${this.renderStyle()} - ${!stateObj - ? html` -
- Entity not available: ${this._config.entity} -
- ` - : html` -
-
- -
-
- ${this._config.name || computeStateName(stateObj)} -
-
-
- ${stateObj.state} - ${this._config.unit || - stateObj.attributes.unit_of_measurement} -
-
${graph}
- `} +
+
+ +
+
+ ${this._config.name || computeStateName(stateObj)} +
+
+
+ ${stateObj.state} + ${this._config.unit || + stateObj.attributes.unit_of_measurement} +
+
${graph}
`; } @@ -399,11 +404,6 @@ class HuiSensorCard extends LitElement implements LovelaceCard { align-self: flex-end; margin: auto 8px; } - .not-found { - flex: 1; - background-color: yellow; - padding: 8px; - } `; } diff --git a/src/panels/lovelace/components/hui-generic-entity-row.ts b/src/panels/lovelace/components/hui-generic-entity-row.ts index d9916ffe69..03ecc5ef08 100644 --- a/src/panels/lovelace/components/hui-generic-entity-row.ts +++ b/src/panels/lovelace/components/hui-generic-entity-row.ts @@ -1,7 +1,3 @@ -import "../../../components/entity/state-badge"; -import "../../../components/ha-relative-time"; -import "../../../components/ha-icon"; - import computeStateName from "../../../common/entity/compute_state_name"; import { LitElement, @@ -11,10 +7,16 @@ import { PropertyValues, property, } from "lit-element"; + import { HomeAssistant } from "../../../types"; import { EntitiesCardEntityConfig } from "../cards/hui-entities-card"; import { computeRTL } from "../../../common/util/compute_rtl"; +import "../../../components/entity/state-badge"; +import "../../../components/ha-relative-time"; +import "../../../components/ha-icon"; +import "../components/hui-warning"; + class HuiGenericEntityRow extends LitElement { @property() public hass?: HomeAssistant; @property() public config?: EntitiesCardEntityConfig; @@ -30,7 +32,13 @@ class HuiGenericEntityRow extends LitElement { if (!stateObj) { return html` -
Entity not available: [[config.entity]]
+ ${this.hass.localize( + "ui.panel.lovelace.warning.entity_not_found", + "entity", + this.config.entity + )} `; } @@ -107,11 +115,6 @@ class HuiGenericEntityRow extends LitElement { display: block; color: var(--secondary-text-color); } - .not-found { - flex: 1; - background-color: yellow; - padding: 8px; - } state-badge { flex: 0 0 40px; } From 4afce7600b4ddf59ea8d10d55c24fe15f58537a1 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Mon, 18 Feb 2019 15:12:40 -0600 Subject: [PATCH 16/18] Convert timer-row to TS/Lit (#2743) * Convert timer-row to TS/Lit * added translations * cleanup * address review comments and fix interval * lint * address review comments * address review comments * address review comments --- .../entity-rows/hui-timer-entity-row.js | 98 -------------- .../entity-rows/hui-timer-entity-row.ts | 128 ++++++++++++++++++ src/translations/en.json | 5 + 3 files changed, 133 insertions(+), 98 deletions(-) delete mode 100644 src/panels/lovelace/entity-rows/hui-timer-entity-row.js create mode 100644 src/panels/lovelace/entity-rows/hui-timer-entity-row.ts diff --git a/src/panels/lovelace/entity-rows/hui-timer-entity-row.js b/src/panels/lovelace/entity-rows/hui-timer-entity-row.js deleted file mode 100644 index fbcfd143d5..0000000000 --- a/src/panels/lovelace/entity-rows/hui-timer-entity-row.js +++ /dev/null @@ -1,98 +0,0 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "../components/hui-generic-entity-row"; - -import timerTimeRemaining from "../../../common/entity/timer_time_remaining"; -import secondsToDuration from "../../../common/datetime/seconds_to_duration"; - -class HuiTimerEntityRow extends PolymerElement { - static get template() { - return html` - - ${this.timerControlTemplate} - - `; - } - - static get timerControlTemplate() { - return html` -
[[_computeDisplay(_stateObj, _timeRemaining)]]
- `; - } - - static get properties() { - return { - hass: Object, - _config: Object, - _stateObj: { - type: Object, - computed: "_computeStateObj(hass.states, _config.entity)", - observer: "_stateObjChanged", - }, - _timeRemaining: Number, - }; - } - - disconnectedCallback() { - super.disconnectedCallback(); - this._clearInterval(); - } - - _stateObjChanged(stateObj) { - if (stateObj) { - this._startInterval(stateObj); - } else { - this._clearInterval(); - } - } - - _clearInterval() { - if (this._updateRemaining) { - clearInterval(this._updateRemaining); - this._updateRemaining = null; - } - } - - _startInterval(stateObj) { - this._clearInterval(); - this._calculateRemaining(stateObj); - - if (stateObj.state === "active") { - this._updateRemaining = setInterval( - () => this._calculateRemaining(this._stateObj), - 1000 - ); - } - } - - _calculateRemaining(stateObj) { - this._timeRemaining = timerTimeRemaining(stateObj); - } - - _computeDisplay(stateObj, time) { - if (!stateObj) return null; - - if (stateObj.state === "idle" || time === 0) return stateObj.state; - - let display = secondsToDuration(time); - - if (stateObj.state === "paused") { - display += " (paused)"; - } - - return display; - } - - _computeStateObj(states, entityId) { - return states && entityId in states ? states[entityId] : null; - } - - setConfig(config) { - if (!config || !config.entity) { - throw new Error("Entity not configured."); - } - this._config = config; - } -} -customElements.define("hui-timer-entity-row", HuiTimerEntityRow); diff --git a/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts b/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts new file mode 100644 index 0000000000..7e7383961d --- /dev/null +++ b/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts @@ -0,0 +1,128 @@ +import { + html, + LitElement, + TemplateResult, + property, + PropertyValues, +} from "lit-element"; + +import "../components/hui-generic-entity-row"; +import "../components/hui-warning"; + +import timerTimeRemaining from "../../../common/entity/timer_time_remaining"; +import secondsToDuration from "../../../common/datetime/seconds_to_duration"; +import { HomeAssistant } from "../../../types"; +import { EntityConfig } from "./types"; +import { HassEntity } from "home-assistant-js-websocket"; + +class HuiTimerEntityRow extends LitElement { + @property() public hass?: HomeAssistant; + @property() private _config?: EntityConfig; + @property() private _timeRemaining?: number; + private _interval?: number; + + public setConfig(config: EntityConfig): void { + if (!config) { + throw new Error("Configuration error"); + } + this._config = config; + } + + public disconnectedCallback(): void { + super.disconnectedCallback(); + this._clearInterval(); + } + + protected render(): TemplateResult | void { + 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._computeDisplay(stateObj)}
+
+ `; + } + + protected updated(changedProps: PropertyValues) { + super.updated(changedProps); + + if (changedProps.has("hass")) { + const stateObj = this.hass!.states[this._config!.entity]; + const oldHass = changedProps.get("hass") as this["hass"]; + const oldStateObj = oldHass + ? oldHass.states[this._config!.entity] + : undefined; + + if (oldStateObj !== stateObj) { + this._startInterval(stateObj); + } else if (!stateObj) { + this._clearInterval(); + } + } + } + + private _clearInterval(): void { + if (this._interval) { + window.clearInterval(this._interval); + this._interval = undefined; + } + } + + private _startInterval(stateObj: HassEntity): void { + this._clearInterval(); + this._calculateRemaining(stateObj); + + if (stateObj.state === "active") { + this._interval = window.setInterval( + () => this._calculateRemaining(stateObj), + 1000 + ); + } + } + + private _calculateRemaining(stateObj: HassEntity): void { + this._timeRemaining = timerTimeRemaining(stateObj); + } + + private _computeDisplay(stateObj: HassEntity): string | null { + if (!stateObj) { + return null; + } + + if (stateObj.state === "idle" || this._timeRemaining === 0) { + return this.hass!.localize("state.timer." + stateObj.state); + } + + let display = secondsToDuration(this._timeRemaining || 0); + + if (stateObj.state === "paused") { + display += ` (${this.hass!.localize("state.timer.paused")})`; + } + + return display; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-timer-entity-row": HuiTimerEntityRow; + } +} + +customElements.define("hui-timer-entity-row", HuiTimerEntityRow); diff --git a/src/translations/en.json b/src/translations/en.json index 35207ed514..9797982c17 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -271,6 +271,11 @@ "off": "[%key:state::default::off%]", "on": "[%key:state::default::on%]" }, + "timer": { + "active": "active", + "idle": "idle", + "paused": "paused" + }, "vacuum": { "cleaning": "Cleaning", "docked": "Docked", From 41343c97742184a0f585be90a944408e294d1559 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 18 Feb 2019 13:14:14 -0800 Subject: [PATCH 17/18] Update translations --- translations/de.json | 65 ++++++++++++++++++++++++++++++---- translations/fr.json | 14 ++++++-- translations/he.json | 4 +-- translations/hu.json | 69 ++++++++++++++++++++++++++++++++---- translations/it.json | 8 ++--- translations/ko.json | 2 +- translations/lb.json | 6 +++- translations/lv.json | 34 ++++++++++++++++-- translations/nb.json | 9 +++-- translations/nl.json | 20 +++++++++-- translations/ru.json | 4 +-- translations/zh-Hans.json | 73 ++++++++++++++++++++++++++++++++++----- 12 files changed, 270 insertions(+), 38 deletions(-) diff --git a/translations/de.json b/translations/de.json index 9a4318d5f5..c1a0c7680c 100644 --- a/translations/de.json +++ b/translations/de.json @@ -346,7 +346,10 @@ }, "customize": { "caption": "Anpassung", - "description": "Elemente anpassen" + "description": "Elemente anpassen", + "picker": { + "header": "Anpassung" + } }, "automation": { "caption": "Automatisierung", @@ -569,20 +572,51 @@ "hub": "Verbunden über", "firmware": "Firmware: {version}", "device_unavailable": "Gerät nicht verfügbar", - "entity_unavailable": "Entität nicht verfügbar" + "entity_unavailable": "Entität nicht verfügbar", + "no_area": "Kein Bereich" } }, "zha": { "caption": "ZHA", - "description": "Zigbee Home Automation Netzwerkmanagement" + "description": "Zigbee Home Automation Netzwerkmanagement", + "services": { + "reconfigure": "Rekonfiguriere ZHA-Gerät (Gerät heilen). Benutze dies, wenn du Probleme mit dem Gerät hast. Wenn es sich bei dem betroffenden Gerät um ein batteriebetriebenes Gerät handelt, stelle sicher dass es wach ist und Kommandos akzeptiert wenn du diesen Dienst benutzt." + } }, "area_registry": { "caption": "Gebietsregister", - "description": "Überblick über alle Bereiche in Deinem Haus." + "description": "Überblick über alle Bereiche in Deinem Haus.", + "no_areas": "Sieht aus, als hättest du noch keine Bereiche!", + "create_area": "BEREICH ERSTELLEN", + "editor": { + "default_name": "Neuer Bereich", + "delete": "LÖSCHEN", + "update": "AKTUALISIEREN", + "create": "ERSTELLEN" + } }, "entity_registry": { "caption": "Entitätsregister", - "description": "Überblick aller bekannten Elemente." + "description": "Überblick aller bekannten Elemente.", + "picker": { + "unavailable": "(nicht verfügbar)" + }, + "editor": { + "unavailable": "Diese Entität ist derzeit nicht verfügbar.", + "default_name": "Neuer Bereich", + "delete": "LÖSCHEN", + "update": "UPDATE" + } + }, + "person": { + "caption": "Personen", + "description": "Verwalte die Personen, die Home Assistant verfolgt.", + "detail": { + "name": "Name", + "device_tracker_intro": "Wähle die Geräte, die dieser Person gehören.", + "device_tracker_picked": "Verfolge Gerät", + "device_tracker_pick": "Wähle zu verfolgendes Gerät" + } } }, "profile": { @@ -727,6 +761,24 @@ } }, "command_line": { + "step": { + "init": { + "data": { + "username": "Benutzername", + "password": "Passwort" + } + }, + "mfa": { + "data": { + "code": "Zwei-Faktor Authentifizierungscode" + }, + "description": "Öffne das **{mfa_module_name}** auf deinem Gerät um den 2-Faktor Authentifizierungscode zu sehen und deine Identität zu bestätigen:" + } + }, + "error": { + "invalid_auth": "Ungültiger Benutzername oder Passwort", + "invalid_code": "Ungültiger Authentifizierungscode" + }, "abort": { "login_expired": "Sitzung abgelaufen, bitte erneut anmelden." } @@ -771,7 +823,8 @@ "pick_card": "Karte auswählen, die hinzugefügt werden soll.", "add": "Karte hinzufügen", "edit": "Bearbeiten", - "delete": "Löschen" + "delete": "Löschen", + "move": "Bewegen" }, "migrate": { "header": "Konfiguration inkompatibel", diff --git a/translations/fr.json b/translations/fr.json index fefd4536db..ef9ff6cfa1 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -569,7 +569,8 @@ "hub": "Connecté via", "firmware": "Firmware: {version}", "device_unavailable": "appareil indisponible", - "entity_unavailable": "entité indisponible" + "entity_unavailable": "entité indisponible", + "no_area": "Pas de pièce" } }, "zha": { @@ -582,14 +583,23 @@ "area_registry": { "caption": "Registre des pièces", "description": "Vue d'ensemble de toutes les pièces de votre maison.", + "picker": { + "header": "Registre des pièces" + }, + "no_areas": "Vous n'avez pas encore configuré de pièce !", + "create_area": "CRÉER UNE PIÈCE", "editor": { - "delete": "SUPPRIMER" + "default_name": "Nouvelle pièce", + "delete": "SUPPRIMER", + "update": "METTRE À JOUR", + "create": "CRÉER" } }, "entity_registry": { "caption": "Registre des entités", "description": "Vue d'ensemble de toutes les entités connues.", "editor": { + "default_name": "Nouvelle pièce", "delete": "SUPPRIMER", "update": "METTRE À JOUR" } diff --git a/translations/he.json b/translations/he.json index b83c91fa14..8d4dffbb35 100644 --- a/translations/he.json +++ b/translations/he.json @@ -370,7 +370,7 @@ "alias": "שם", "triggers": { "header": "טריגרים", - "introduction": "טריגרים הם מה שמתחיל כל אוטומציה. ניתן לציין מספר טריגרים עבור אותו כלל. לאחר הפעלת טריגר, ה - Home Assistant יאמת את התנאים, אם קיימים, ויקרא לפעולה. \n\n[למד עוד על טריגרים](https:\/\/home-assistant.io\/docs\/automation\/trigger\/)", + "introduction": "טריגרים הם מה שמתחיל כל אוטומציה. ניתן לציין מספר טריגרים עבור אותו כלל. לאחר הפעלת טריגר, Home Assistant יאמת את התנאים, אם ישנם, ויפעיל את הפעולה. \n\n[למד עוד על טריגרים](https:\/\/home-assistant.io\/docs\/automation\/trigger\/)", "add": "הוספת טריגר", "duplicate": "שכפל", "delete": "מחק", @@ -451,7 +451,7 @@ }, "conditions": { "header": "תנאים", - "introduction": "התנאים הם חלק אופציונלי של כלל אוטומציה, וניתן להשתמש בהם כדי למנוע פעולה כלשהי בעת הפעלתה. התנאים נראים דומים מאוד לטריגרים אך הם שונים מאוד. הטריגר יסתכל על האירועים המתרחשים במערכת בעוד תנאי רק מסתכל על איך המערכת נראית עכשיו. הטריגר יכול שמתג נדלק. תנאי יכול לראות רק אם מתג מופעל או כבוי. \n\n[למידע נוסף על תנאים](Https:\/\/home-assistant.io\/docs\/scripts\/conditions\/)", + "introduction": "התנאים הם חלק אופציונלי של כלל אוטומציה, וניתן להשתמש בהם כדי למנוע פעולה כלשהי בעת הפעלתה. התנאים נראים דומים מאוד לטריגרים אך הם שונים מאוד. הטריגר יסתכל על האירועים המתרחשים במערכת בעוד תנאי רק מסתכל על איך המערכת נראית עכשיו. הטריגר יכול לדעת כשמתג נדלק. תנאי יכול לראות רק אם מתג מופעל או כבוי. \n\n[למידע נוסף על תנאים](Https:\/\/home-assistant.io\/docs\/scripts\/conditions\/)", "add": "הוסף תנאי", "duplicate": "שכפל", "delete": "מחק", diff --git a/translations/hu.json b/translations/hu.json index 28713a55b8..05a56a2959 100644 --- a/translations/hu.json +++ b/translations/hu.json @@ -346,7 +346,10 @@ }, "customize": { "caption": "Testreszabás", - "description": "Entitások testreszabása" + "description": "Entitások testreszabása", + "picker": { + "header": "Testreszabás" + } }, "automation": { "caption": "Automatizálás", @@ -436,6 +439,7 @@ "seconds": "Másodperc" }, "geo_location": { + "label": "Helylokáció", "source": "Forrás", "zone": "Zóna", "event": "Esemény:", @@ -568,20 +572,55 @@ "hub": "Kapcsolódva", "firmware": "Firmware: {version}", "device_unavailable": "eszköz nem érhető el", - "entity_unavailable": "entitás nem érhető el" + "entity_unavailable": "entitás nem érhető el", + "no_area": "Nincs Terület" } }, "zha": { "caption": "ZHA", - "description": "Zigbee Home Automation hálózat menedzsment" + "description": "Zigbee Home Automation hálózat menedzsment", + "services": { + "reconfigure": "A ZHA készülék újratelepítése (eszköz rendbehozatala). Ezt a funkciót használd, ha problémáid vannak a készülékkel. Ha a kérdéses eszköz akkumulátoros, győződj meg róla, hogy nincs alvó állapotban és fogadja a parancsokat, amikor ezt a szolgáltatást használod." + } }, "area_registry": { "caption": "Terület Nyilvántartás", - "description": "Az összes otthoni terület áttekintése" + "description": "Az összes otthoni terület áttekintése", + "picker": { + "header": "Terület Nyilvántartás" + }, + "no_areas": "Úgy tűnik nem hoztál létre még egy területet sem!", + "create_area": "TERÜLET LÉTREHOZÁSA", + "editor": { + "default_name": "Új Terület", + "delete": "TÖRLÉS", + "update": "FRISSÍTÉS", + "create": "LÉTREHOZÁS" + } }, "entity_registry": { "caption": "Entitás Nyilvántartás", - "description": "Az összes ismert entitás áttekintése" + "description": "Az összes ismert entitás áttekintése", + "picker": { + "header": "Entitás Nyilvántartás", + "unavailable": "(nem elérhető)" + }, + "editor": { + "unavailable": "Ez a entitás jelenleg nem elérhető.", + "default_name": "Új Terület", + "delete": "TÖRLÉS", + "update": "FRISSÍTÉS" + } + }, + "person": { + "caption": "Személyek", + "description": "Kezeld azon személyeket, melyeket a Home Assistant követ.", + "detail": { + "name": "Név", + "device_tracker_intro": "Válaszd ki az eszközöket, melyek ehhez a felhasználóhoz tartoznak", + "device_tracker_picked": "Eszköz követése", + "device_tracker_pick": "Válassz egy követni kívánt eszközt" + } } }, "profile": { @@ -726,6 +765,23 @@ } }, "command_line": { + "step": { + "init": { + "data": { + "username": "Felhasználónév", + "password": "Jelszó" + } + }, + "mfa": { + "data": { + "code": "Két faktoros hitelesítő kód" + } + } + }, + "error": { + "invalid_auth": "Érvénytelen felhasználónév vagy jelszó", + "invalid_code": "Érvénytelen hitelesítő kód" + }, "abort": { "login_expired": "A munkamenet lejárt, kérlek, jelentkezz be újra." } @@ -770,7 +826,8 @@ "pick_card": "Válaszd ki a kártyát amit hozzá szeretnél adni.", "add": "Kártya hozzáadása", "edit": "Szerkesztés", - "delete": "Törlés" + "delete": "Törlés", + "move": "Mozgatás" }, "migrate": { "header": "Inkompatibilis Konfiguráció", diff --git a/translations/it.json b/translations/it.json index 68ebe62252..a2e3269845 100644 --- a/translations/it.json +++ b/translations/it.json @@ -1003,7 +1003,7 @@ }, "relative_time": { "past": "{time} fa", - "future": "{time} fa", + "future": "tra {time}", "never": "Mai", "duration": { "second": "{count} {count, plural,\none {secondo}\nother {secondi}\n}", @@ -1036,9 +1036,9 @@ "last_action": "Ultima azione" }, "sun": { - "elevation": "Alba", - "rising": "Tramonto", - "setting": "Impostazione" + "elevation": "Elevazione", + "rising": "Alba", + "setting": "Tramonto" }, "updater": { "title": "Aggiorna istruzioni" diff --git a/translations/ko.json b/translations/ko.json index 1c80440032..ede0790c05 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -241,7 +241,7 @@ } }, "weather": { - "clear-night": "맑은 밤", + "clear-night": "맑음 (밤)", "cloudy": "흐림", "fog": "안개", "hail": "우박", diff --git a/translations/lb.json b/translations/lb.json index e69fac9224..204aa9e474 100644 --- a/translations/lb.json +++ b/translations/lb.json @@ -850,6 +850,9 @@ "para_sure": "Sécher fir d'Kontrolle iwwert de Benotzer Interface z'iwwerhuelen?", "cancel": "Vergiess et", "save": "Kontroll iwwerhuelen" + }, + "menu": { + "raw_editor": "Editeur fir déi reng Konfiguratioun" } }, "menu": { @@ -929,7 +932,8 @@ "arm_home": "Aktivéiert Doheem", "arm_away": "Aktivéiert Ënnerwee", "arm_night": "Aktivéiert Nuecht", - "armed_custom_bypass": "Personaliséierte Bypass" + "armed_custom_bypass": "Personaliséierte Bypass", + "arm_custom_bypass": "Personaliséierte Bypass" }, "automation": { "last_triggered": "Läscht ausgeléist", diff --git a/translations/lv.json b/translations/lv.json index 1bc88e9647..e93c68bcc8 100644 --- a/translations/lv.json +++ b/translations/lv.json @@ -433,6 +433,9 @@ "hours": "Stundas", "minutes": "Minūtes", "seconds": "Sekundes" + }, + "geo_location": { + "label": "Ģeogrāfiskā atrašanās vieta" } } }, @@ -566,6 +569,9 @@ "zha": { "caption": "ZHA", "description": "Zigbee Home Automation tīkla pārvaldība" + }, + "area_registry": { + "description": "Pārskats par visām vietām jūsu mājās." } }, "profile": { @@ -708,6 +714,26 @@ "abort": { "not_whitelisted": "Jūsu dators nav iekļauts baltajā sarakstā." } + }, + "command_line": { + "step": { + "init": { + "data": { + "username": "Lietotājvārds", + "password": "Parole" + } + }, + "mfa": { + "data": { + "code": "Divpakāpju Autorizācijas Kods" + }, + "description": "Atveriet **{mfa_module_name}** Jūsu ierīcē, lai apskatītu savu divpakāpju autorizācijas kodu un aptiprinātu savu identitāti:" + } + }, + "error": { + "invalid_auth": "Nepareizs lietotājvārds un parole", + "invalid_code": "Nepareizs autorizācijas kods" + } } } } @@ -841,7 +867,8 @@ "arm_home": "Pieslēgt mājas", "arm_away": "Pieslēgt prombūtni", "arm_night": "Pieslēgts uz nakti", - "armed_custom_bypass": "Pielāgots apvedceļš" + "armed_custom_bypass": "Pielāgots apvedceļš", + "arm_custom_bypass": "Pielāgots apvedceļš" }, "automation": { "last_triggered": "Pēdējais izsaukums", @@ -1001,7 +1028,10 @@ "weblink": "Weblink", "zwave": "Z-Wave", "vacuum": "Putekļsūcējs", - "zha": "ZHA" + "zha": "ZHA", + "hassio": "Hass.io", + "homeassistant": "Home Assistant", + "lovelace": "Lovelace" }, "attribute": { "weather": { diff --git a/translations/nb.json b/translations/nb.json index 15160f76a5..b249d72ecc 100644 --- a/translations/nb.json +++ b/translations/nb.json @@ -588,6 +588,7 @@ "picker": { "header": "Områderegister" }, + "no_areas": "Det ser ikke ut som om du har noen områder ennå!", "create_area": "OPPRETT OMRÅDE", "editor": { "default_name": "Nytt område", @@ -612,9 +613,12 @@ }, "person": { "caption": "Personer", + "description": "Administrer personer som Home Assistant sporer.", "detail": { "name": "Navn", - "device_tracker_intro": "Velg enhetene som tilhører denne personen." + "device_tracker_intro": "Velg enhetene som tilhører denne personen.", + "device_tracker_picked": "Spor enhet", + "device_tracker_pick": "Velg en enhet å spore" } } }, @@ -769,7 +773,8 @@ } }, "error": { - "invalid_auth": "Ugyldig brukernavn eller passord" + "invalid_auth": "Ugyldig brukernavn eller passord", + "invalid_code": "Ugyldig autentiseringskode" }, "abort": { "login_expired": "Økten er utløpt, vennligst logg inn på nytt" diff --git a/translations/nl.json b/translations/nl.json index 3bd99c6947..0e37541299 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -581,11 +581,27 @@ }, "area_registry": { "caption": "Gebiedenregister", - "description": "Overzicht van alle gebieden in je huis." + "description": "Overzicht van alle gebieden in je huis.", + "picker": { + "header": "Gebiedenregister" + } }, "entity_registry": { "caption": "Entiteiten register", - "description": "Overzicht van alle gekende entiteiten" + "description": "Overzicht van alle gekende entiteiten", + "picker": { + "header": "Entiteiten register" + }, + "editor": { + "delete": "VERWIJDEREN" + } + }, + "person": { + "caption": "Personen", + "description": "Beheer de personen die Home Assistant volgt.", + "detail": { + "name": "Naam" + } } }, "profile": { diff --git a/translations/ru.json b/translations/ru.json index 78ec3f9548..5a3c8ccbd9 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -370,7 +370,7 @@ "alias": "Название", "triggers": { "header": "Триггеры", - "introduction": "Триггеры-это то, что начинает процесс обработки правила автоматизации. Можно указать несколько триггеров на одно и то же правило. Как только триггер срабатывает, Home Assistant будет проверять условия, если таковые имеются, и вызвать действие.\n\n[Узнать больше о триггерах.](https:\/\/home-assistant.io\/docs\/automation\/trigger\/)", + "introduction": "Триггеры - это то, что запускает процесс автоматизации. Можно указать несколько триггеров на одно и то же правило. Как только триггер срабатывает, Home Assistant будет проверять условия, и, если таковые имеются, выполнить действие.\n\n[Узнать больше о триггерах.](https:\/\/home-assistant.io\/docs\/automation\/trigger\/)", "add": "Добавить триггер", "duplicate": "Дублировать", "delete": "Удалить", @@ -590,7 +590,7 @@ "picker": { "header": "Управление помещениями" }, - "no_areas": "У Вас еще нет добавленных помещений.", + "no_areas": "Похоже, что у Вас пока ещё нет добавленных помещений!", "create_area": "ДОБАВИТЬ", "editor": { "default_name": "Новое помещение", diff --git a/translations/zh-Hans.json b/translations/zh-Hans.json index 3773b59259..854bd21177 100644 --- a/translations/zh-Hans.json +++ b/translations/zh-Hans.json @@ -346,7 +346,11 @@ }, "customize": { "caption": "自定义", - "description": "自定义实体" + "description": "自定义实体", + "picker": { + "header": "自定义", + "introduction": "调整每个实体的属性。添加\/编辑的自定义设置将立即生效,删除的自定义设置将在实体更新时生效。" + } }, "automation": { "caption": "自动化", @@ -568,17 +572,50 @@ "hub": "链接于", "firmware": "固件:{version}", "device_unavailable": "设备不可用", - "entity_unavailable": "实体不可用" + "entity_unavailable": "实体不可用", + "no_area": "没有区域" } }, "zha": { "description": "Zigbee 智能家居(ZHA) 网络管理" }, "area_registry": { - "description": "您家中所有区域的概览。" + "description": "您家中所有区域的概览。", + "picker": { + "header": "注册区域" + }, + "no_areas": "看来你还没有建立区域!", + "create_area": "创建区域", + "editor": { + "default_name": "新区域", + "delete": "删除", + "update": "更新", + "create": "创建" + } }, "entity_registry": { - "description": "所有已知实体的概览。" + "caption": "实体注册", + "description": "所有已知实体的概览。", + "picker": { + "header": "实体注册", + "unavailable": "(不可用)" + }, + "editor": { + "unavailable": "该实体暂不可用。", + "default_name": "新区域", + "delete": "删除", + "update": "更新" + } + }, + "person": { + "caption": "人", + "description": "管理Home Assistant跟踪的人员。", + "detail": { + "name": "名字", + "device_tracker_intro": "选择属于此人的设备。", + "device_tracker_picked": "跟踪设备", + "device_tracker_pick": "选择要跟踪的设备" + } } }, "profile": { @@ -674,7 +711,7 @@ "data": { "code": "双重认证口令" }, - "description": "在设备上打开 **{mfa_module_name}** 来查看双重认证口令以验证您的身份:" + "description": "在设备上打开 **{mfa_module_name}** 查看双重认证口令并验证您的身份:" } }, "error": { @@ -697,7 +734,7 @@ "data": { "code": "双重认证口令" }, - "description": "在设备上打开 **{mfa_module_name}** 来查看双重认证口令以验证您的身份:" + "description": "在设备上打开 **{mfa_module_name}** 查看双重认证口令并验证您的身份:" } }, "error": { @@ -723,6 +760,24 @@ } }, "command_line": { + "step": { + "init": { + "data": { + "username": "用户名", + "password": "密码" + } + }, + "mfa": { + "data": { + "code": "二次认证口令" + }, + "description": "在设备上打开 **{mfa_module_name}** 查看二次认证口令并验证您的身份:" + } + }, + "error": { + "invalid_auth": "无效的用户名或密码", + "invalid_code": "无效的验证码" + }, "abort": { "login_expired": "会话已过期,请重新登录。" } @@ -767,7 +822,8 @@ "pick_card": "请选择要添加的卡片。", "add": "添加卡片", "edit": "编辑", - "delete": "删除" + "delete": "删除", + "move": "移动" }, "migrate": { "header": "配置不兼容", @@ -870,7 +926,8 @@ "arm_home": "在家警戒", "arm_away": "离家警戒", "arm_night": "夜间警戒", - "armed_custom_bypass": "自定义略过" + "armed_custom_bypass": "自定义略过", + "arm_custom_bypass": "自定义略过条件" }, "automation": { "last_triggered": "上次触发", From 392af26503759ba49d68f3873e0c4c0ae6401ebf Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 18 Feb 2019 13:14:20 -0800 Subject: [PATCH 18/18] Bumped version to 20190218.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 65ef259734..a1add8ada4 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20190216.0", + version="20190218.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors",