From 1b9f224569b458e4c6cdf9762dd0c643514c5df7 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Wed, 15 Apr 2020 00:32:58 +0000 Subject: [PATCH 01/36] [ci skip] Translation update --- translations/el.json | 17 ++++++++++++++++- translations/pt-BR.json | 31 ++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/translations/el.json b/translations/el.json index 295687eadc..71d2e77edd 100644 --- a/translations/el.json +++ b/translations/el.json @@ -1604,6 +1604,10 @@ "search_again": "Αναζήτηση ξανά", "spinner": "Αναζήτηση συσκευών ZHA Zigbee…" }, + "add": { + "caption": "Προσθήκη Συσκευών", + "description": "Προσθήκη συσκετών στο δίκτυο Zigbee" + }, "caption": "ZHA", "cluster_attributes": { "attributes_of_cluster": "Χαρακτηριστικά της επιλεγμένης συστοιχίας", @@ -1639,19 +1643,25 @@ "device_name_placeholder": "Όνομα χρήστη", "update_name_button": "Ενημέρωση ονόματος" }, + "devices": { + "header": "Zigbee Home Automation - Συσκευή" + }, "groups": { "add_members": "Προσθήκη Μελών", "adding_members": "Προσθήκη Μελών", + "caption": "Ομάδες", "create": "Δημιουργία ομάδας", "create_group": "Zigbee Home Automation - Δημιουργία ομάδας", "create_group_details": "Καταχωρείστε τις απαραίτητες πληροφορίες για να δημιουργήσετε μια νέα ομάδα Zigbee", "creating_group": "Δημιουργία ομάδας", + "description": "Δημιούργησε και τροποποίησε ομάδες Zigbee", "group_details": "Εδώ βρίσκονται όλες οι πληροφορίες για την επιλεγμένη ομάδα", "group_id": "Αναγνωριστικό ομάδας", "group_info": "Πληροφορίες ομάδας", "group_name_placeholder": "Όνομα ομάδας", "group_not_found": "Η ομάδα δεν βρέθηκε!", "groups": "Ομάδες", + "groups-header": "Zigbee Home Automation - Διαχείριση Ομάδων", "header": "Zigbee Home Automation - Διαχείριση Ομάδων", "introduction": "Δημιουργήστε και τροποποιήστε ομάδες Zigbee", "manage_groups": "Διαχειριστείτε τις ομάδες Zigbee", @@ -1662,6 +1672,7 @@ "removing_members": "Αφαίρεση Μελών", "zha_zigbee_groups": "ZHA oμάδες Zigbee" }, + "introduction": "Εδώ μπορείς να παραμετροποιήσεις την ενοποίηση ZHA. Δεν είναι ακόμα δυνατό να παραμετροποιηθούν τα πάντα μέσω του γραφικού περιβάλλοντος εργασίας, αλλά το δουλεύουμε.", "network_management": { "header": "Διαχείριση δικτύου", "introduction": "Εντολές που επηρεάζουν ολόκληρο το δίκτυο" @@ -1677,7 +1688,8 @@ "reconfigure": "Ρυθμίστε ξανά τη συσκευή ZHA (heal συσκευή). Χρησιμοποιήστε αυτήν την επιλογή εάν αντιμετωπίζετε ζητήματα με τη συσκευή. Εάν η συγκεκριμένη συσκευή τροφοδοτείται από μπαταρία βεβαιωθείτε ότι είναι ενεργοποιημένη και δέχεται εντολές όταν χρησιμοποιείτε αυτή την υπηρεσία.", "remove": "Καταργήστε μια συσκευή από το δίκτυο ZigΒee.", "updateDeviceName": "Ορίστε ένα προσαρμοσμένο όνομα γι αυτήν τη συσκευή στο μητρώο συσκευών." - } + }, + "title": "Zigbee Home Automation" }, "zone": { "edit_home_zone": "Η τοποθεσία του σπιτιού σας μπορεί να αλλαχτεί από τις γενικές ρυθμίσεις." @@ -1862,6 +1874,9 @@ "showing_entries": "Εμφανίζοντα καταχωρήσεις για" }, "lovelace": { + "add_entities": { + "saving_failed": "Η αποθήκευση της παραμετροποίησης του Lovelace απέτυχε" + }, "cards": { "confirm_delete": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν την κάρτα;", "empty_state": { diff --git a/translations/pt-BR.json b/translations/pt-BR.json index d3c9cc043a..6f8e1d55e5 100644 --- a/translations/pt-BR.json +++ b/translations/pt-BR.json @@ -643,6 +643,15 @@ "default_confirmation_title": "Você tem certeza?", "ok": "OK" }, + "helper_settings": { + "input_number": { + "step": "Tamanho da etapa" + }, + "input_text": { + "max": "Comprimento máximo", + "min": "Comprimento mínimo" + } + }, "more_info_control": { "dismiss": "Dispensar diálogo", "edit": "Editar entidade", @@ -1424,7 +1433,16 @@ "introduction": "Aqui é possível configurar seus componentes e Home Assistant. Nem tudo é possível configurar via UI, mas estamos trabalhando nisso.", "lovelace": { "dashboards": { - "default_dashboard": "Este é o painel de instrumentos padrão" + "cant_edit_default": "O painel padrão do Lovelace não pode ser editado a partir da UI. Você pode ocultá-lo definindo outro painel como padrão.", + "cant_edit_yaml": "Os painéis definidos no YAML não podem ser editados a partir da UI. Altere-os em configuration.yaml.", + "default_dashboard": "Este é o painel de instrumentos padrão", + "detail": { + "icon": "Ícone", + "title": "Título" + }, + "picker": { + "open": "Aberto" + } } }, "person": { @@ -1663,9 +1681,11 @@ }, "groups": { "caption": "Grupos", + "create_group": "Zigbee Automação Residencial - Criar Grupo", "description": "Criar e modificar grupos Zigbee", "group-header": "Zigbee Home Automation - Detalhes do Grupo", "groups-header": "Zigbee Home Automation - Gerenciamento de grupos", + "header": "Zigbee Automação Residencial - Gestão de Grupo", "zha_zigbee_groups": "Grupos ZHA Zigbee" }, "network_management": { @@ -1891,6 +1911,11 @@ "showing_entries": "Exibindo registros de" }, "lovelace": { + "add_entities": { + "generated_unsupported": "Você só pode usar esta função quando tiver assumido o controle da UI do Lovelace.", + "saving_failed": "Falha ao salvar a configuração da UI do Lovelace.", + "yaml_unsupported": "Você não pode usar esta função ao usar a UI do Lovelace no modo YAML." + }, "cards": { "confirm_delete": "Tem certeza de que deseja excluir este cartão?", "empty_state": { @@ -2121,6 +2146,10 @@ "para_sure": "Tem certeza de que deseja assumir o controle da sua interface de usuário?", "save": "Assuma o controle" }, + "suggest_card": { + "add": "Adicionar a UI do Lovelace", + "create_own": "Escolha cartão diferente" + }, "view": { "panel_mode": { "description": "Isso renderiza o primeiro cartão em largura total; outros cartões nesta visualização não serão renderizados.", From 8383caf6a6b9150e5cc9624730523ed8f9f6131e Mon Sep 17 00:00:00 2001 From: "David F. Mulcahey" Date: Wed, 15 Apr 2020 09:36:48 -0400 Subject: [PATCH 02/36] Add ability to see Zigbee information for a device (#5445) * add ability to see zigbee information for a device * cleanup * handle resize correctly * cleanup * convert to ha-dialog * Simplify * Add close button * Add readonly to code editor * add class * eslint fixes Co-authored-by: Bram Kragten --- src/components/ha-code-editor.ts | 5 +- src/data/zha.ts | 1 + .../dialog-zha-device-zigbee-info.ts | 70 +++++++++++++++++++ .../show-dialog-zha-device-zigbee-info.ts | 22 ++++++ src/panels/config/zha/zha-device-card.ts | 26 +++++++ src/translations/en.json | 7 +- 6 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 src/dialogs/zha-device-zigbee-signature-dialog/dialog-zha-device-zigbee-info.ts create mode 100644 src/dialogs/zha-device-zigbee-signature-dialog/show-dialog-zha-device-zigbee-info.ts diff --git a/src/components/ha-code-editor.ts b/src/components/ha-code-editor.ts index 7986aa7467..eee7214179 100644 --- a/src/components/ha-code-editor.ts +++ b/src/components/ha-code-editor.ts @@ -20,7 +20,9 @@ export class HaCodeEditor extends UpdatingElement { @property() public mode?: string; - @property() public autofocus = false; + @property({ type: Boolean }) public autofocus = false; + + @property({ type: Boolean }) public readOnly = false; @property() public rtl = false; @@ -128,6 +130,7 @@ export class HaCodeEditor extends UpdatingElement { mode: this.mode, autofocus: this.autofocus !== false, viewportMargin: Infinity, + readOnly: this.readOnly, extraKeys: { Tab: "indentMore", "Shift-Tab": "indentLess", diff --git a/src/data/zha.ts b/src/data/zha.ts index 0507747150..af8f79be8d 100644 --- a/src/data/zha.ts +++ b/src/data/zha.ts @@ -23,6 +23,7 @@ export interface ZHADevice { power_source?: string; area_id?: string; device_type: string; + signature: any; } export interface Attribute { diff --git a/src/dialogs/zha-device-zigbee-signature-dialog/dialog-zha-device-zigbee-info.ts b/src/dialogs/zha-device-zigbee-signature-dialog/dialog-zha-device-zigbee-info.ts new file mode 100644 index 0000000000..0ba57e4c40 --- /dev/null +++ b/src/dialogs/zha-device-zigbee-signature-dialog/dialog-zha-device-zigbee-info.ts @@ -0,0 +1,70 @@ +import { + CSSResult, + customElement, + html, + LitElement, + property, + TemplateResult, +} from "lit-element"; +import "../../components/ha-code-editor"; +import { createCloseHeading } from "../../components/ha-dialog"; +import { haStyleDialog } from "../../resources/styles"; +import { HomeAssistant } from "../../types"; +import { ZHADeviceZigbeeInfoDialogParams } from "./show-dialog-zha-device-zigbee-info"; + +@customElement("dialog-zha-device-zigbee-info") +class DialogZHADeviceZigbeeInfo extends LitElement { + @property() public hass!: HomeAssistant; + + @property() private _signature: any; + + public async showDialog( + params: ZHADeviceZigbeeInfoDialogParams + ): Promise { + this._signature = JSON.stringify( + { + ...params.device.signature, + manufacturer: params.device.manufacturer, + model: params.device.model, + class: params.device.quirk_class, + }, + null, + 2 + ); + } + + protected render(): TemplateResult { + if (!this._signature) { + return html``; + } + + return html` + + + + + `; + } + + private _close(): void { + this._signature = undefined; + } + + static get styles(): CSSResult { + return haStyleDialog; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-zha-device-zigbee-info": DialogZHADeviceZigbeeInfo; + } +} diff --git a/src/dialogs/zha-device-zigbee-signature-dialog/show-dialog-zha-device-zigbee-info.ts b/src/dialogs/zha-device-zigbee-signature-dialog/show-dialog-zha-device-zigbee-info.ts new file mode 100644 index 0000000000..26df394b7a --- /dev/null +++ b/src/dialogs/zha-device-zigbee-signature-dialog/show-dialog-zha-device-zigbee-info.ts @@ -0,0 +1,22 @@ +import { fireEvent } from "../../common/dom/fire_event"; +import { ZHADevice } from "../../data/zha"; + +export interface ZHADeviceZigbeeInfoDialogParams { + device: ZHADevice; +} + +export const loadZHADeviceZigbeeInfoDialog = () => + import( + /* webpackChunkName: "dialog-zha-device-zigbee-info" */ "./dialog-zha-device-zigbee-info" + ); + +export const showZHADeviceZigbeeInfoDialog = ( + element: HTMLElement, + zhaDeviceZigbeeInfoParams: ZHADeviceZigbeeInfoDialogParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-zha-device-zigbee-info", + dialogImport: loadZHADeviceZigbeeInfoDialog, + dialogParams: zhaDeviceZigbeeInfoParams, + }); +}; diff --git a/src/panels/config/zha/zha-device-card.ts b/src/panels/config/zha/zha-device-card.ts index af597ec060..5d7d887664 100644 --- a/src/panels/config/zha/zha-device-card.ts +++ b/src/panels/config/zha/zha-device-card.ts @@ -41,6 +41,7 @@ import { HomeAssistant } from "../../../types"; import { addEntitiesToLovelaceView } from "../../lovelace/editor/add-entities-to-view"; import { formatAsPaddedHex } from "./functions"; import { ItemSelectedEvent, NodeServiceData } from "./types"; +import { showZHADeviceZigbeeInfoDialog } from "../../../dialogs/zha-device-zigbee-signature-dialog/show-dialog-zha-device-zigbee-info"; declare global { // for fire event @@ -367,6 +368,24 @@ class ZHADeviceCard extends LitElement { : ""} ` : ""} + ${this.device!.device_type !== "Coordinator" + ? html` + + ${this.hass!.localize( + "ui.dialogs.zha_device_info.buttons.zigbee_information" + )} + + ${this.showHelp + ? html` +
+ ${this.hass!.localize( + "ui.dialogs.zha_device_info.services.zigbee_information" + )} +
+ ` + : ""} + ` + : ""} ` : "" @@ -437,6 +456,10 @@ class ZHADeviceCard extends LitElement { navigate(this, "/config/zha/add/" + this.device!.ieee); } + private async _handleZigbeeInfoClicked() { + showZHADeviceZigbeeInfoDialog(this, { device: this.device! }); + } + private _addToLovelaceView(): void { addEntitiesToLovelaceView( this, @@ -528,6 +551,9 @@ class ZHADeviceCard extends LitElement { padding-right: 28px; padding-bottom: 10px; } + .buttons .icon { + margin-right: 16px; + } `, ]; } diff --git a/src/translations/en.json b/src/translations/en.json index 7a721a4857..1d2cb0a058 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -719,15 +719,18 @@ "zha_device_info": { "manuf": "by {manufacturer}", "no_area": "No Area", + "device_signature": "Zigbee device signature", "buttons": { "add": "Add Devices", "remove": "Remove Device", - "reconfigure": "Reconfigure Device" + "reconfigure": "Reconfigure Device", + "zigbee_information": "Zigbee Information" }, "services": { "reconfigure": "Reconfigure ZHA device (heal device). Use this if you are having issues with the device. If the device in question is a battery powered device please ensure it is awake and accepting commands when you use this service.", "updateDeviceName": "Set a custom name for this device in the device registry.", - "remove": "Remove a device from the Zigbee network." + "remove": "Remove a device from the Zigbee network.", + "zigbee_information": "View the Zigbee information for the device." }, "confirmations": { "remove": "Are you sure that you want to remove the device?" From 4f81085d0f1dc88d66a97e7ad047be595772cd97 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 15 Apr 2020 06:59:33 -0700 Subject: [PATCH 03/36] Add entity row that displays static text (#5516) * Add entity row that displays text * Remove hass type --- .../create-element/create-row-element.ts | 1 + src/panels/lovelace/entity-rows/types.ts | 9 ++- .../lovelace/special-rows/hui-text-row.ts | 69 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/panels/lovelace/special-rows/hui-text-row.ts diff --git a/src/panels/lovelace/create-element/create-row-element.ts b/src/panels/lovelace/create-element/create-row-element.ts index e29f8ea9b8..80533bf0e5 100644 --- a/src/panels/lovelace/create-element/create-row-element.ts +++ b/src/panels/lovelace/create-element/create-row-element.ts @@ -41,6 +41,7 @@ const LAZY_LOAD_TYPES = { cast: () => import("../special-rows/hui-cast-row"), buttons: () => import("../special-rows/hui-buttons-row"), attribute: () => import("../special-rows/hui-attribute-row"), + text: () => import("../special-rows/hui-text-row"), }; const DOMAIN_TO_ELEMENT_TYPE = { _domain_not_found: "text", diff --git a/src/panels/lovelace/entity-rows/types.ts b/src/panels/lovelace/entity-rows/types.ts index 1407cc4563..4b674a9d6f 100644 --- a/src/panels/lovelace/entity-rows/types.ts +++ b/src/panels/lovelace/entity-rows/types.ts @@ -29,6 +29,12 @@ export interface WeblinkConfig { icon?: string; url: string; } +export interface TextConfig { + type: "text"; + name: string; + icon?: string; + text: string; +} export interface CallServiceConfig extends EntityConfig { type: "call-service"; service: string; @@ -65,7 +71,8 @@ export type LovelaceRowConfig = | ButtonRowConfig | ButtonsRowConfig | ConditionalRowConfig - | AttributeRowConfig; + | AttributeRowConfig + | TextConfig; export interface LovelaceRow extends HTMLElement { hass?: HomeAssistant; diff --git a/src/panels/lovelace/special-rows/hui-text-row.ts b/src/panels/lovelace/special-rows/hui-text-row.ts new file mode 100644 index 0000000000..fac5b08046 --- /dev/null +++ b/src/panels/lovelace/special-rows/hui-text-row.ts @@ -0,0 +1,69 @@ +import { + html, + LitElement, + TemplateResult, + customElement, + property, + css, + CSSResult, +} from "lit-element"; + +import { LovelaceRow, TextConfig } from "../entity-rows/types"; + +import "../../../components/ha-icon"; + +@customElement("hui-text-row") +class HuiTextRow extends LitElement implements LovelaceRow { + @property() private _config?: TextConfig; + + public setConfig(config: TextConfig): void { + if (!config || !config.name || !config.text) { + throw new Error("Invalid Configuration: 'name' and 'text' required"); + } + + this._config = config; + } + + protected render(): TemplateResult { + if (!this._config) { + return html``; + } + + return html` + +
${this._config.name}
+
${this._config.text}
+ `; + } + + static get styles(): CSSResult { + return css` + :host { + display: flex; + align-items: center; + } + ha-icon { + padding: 8px; + color: var(--paper-item-icon-color); + } + div { + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .name { + margin-left: 16px; + } + .text { + text-align: right; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-text-row": HuiTextRow; + } +} From ed54a185e4393f4f456c30c5a29305c19302c270 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 15 Apr 2020 07:00:16 -0700 Subject: [PATCH 04/36] Remove srcset from brands (#5517) --- src/dialogs/config-flow/step-flow-pick-handler.ts | 3 --- src/panels/config/devices/ha-config-device-page.ts | 7 +------ .../config/integrations/ha-config-entries-dashboard.ts | 3 --- src/panels/developer-tools/info/integrations-card.ts | 3 --- 4 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/dialogs/config-flow/step-flow-pick-handler.ts b/src/dialogs/config-flow/step-flow-pick-handler.ts index b060069e31..c6bee2c316 100644 --- a/src/dialogs/config-flow/step-flow-pick-handler.ts +++ b/src/dialogs/config-flow/step-flow-pick-handler.ts @@ -88,9 +88,6 @@ class StepFlowPickHandler extends LitElement { slot="item-icon" loading="lazy" src="https://brands.home-assistant.io/_/${handler.slug}/icon.png" - srcset=" - https://brands.home-assistant.io/_/${handler.slug}/icon@2x.png 2x - " referrerpolicy="no-referrer" /> diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index bb2daabd0c..3b9688d930 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -174,7 +174,7 @@ export class HaConfigDevicePage extends LitElement { >
-
+
${ this.narrow ? "" @@ -213,11 +213,6 @@ export class HaConfigDevicePage extends LitElement { src="https://brands.home-assistant.io/${ integrations[0] }/logo.png" - srcset=" - https://brands.home-assistant.io/${ - integrations[0] - }/logo@2x.png 2x - " referrerpolicy="no-referrer" @load=${this._onImageLoad} @error=${this._onImageError} diff --git a/src/panels/config/integrations/ha-config-entries-dashboard.ts b/src/panels/config/integrations/ha-config-entries-dashboard.ts index 6873673dd2..2d1efda9c7 100644 --- a/src/panels/config/integrations/ha-config-entries-dashboard.ts +++ b/src/panels/config/integrations/ha-config-entries-dashboard.ts @@ -203,9 +203,6 @@ export class HaConfigManagerDashboard extends LitElement { From 4c3069e5b7102432549db088fac407670d9d0bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 15 Apr 2020 20:15:34 +0200 Subject: [PATCH 05/36] Add missing imports (#5547) --- src/panels/config/helpers/forms/ha-input_datetime-form.ts | 2 ++ src/panels/config/helpers/forms/ha-input_number-form.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/panels/config/helpers/forms/ha-input_datetime-form.ts b/src/panels/config/helpers/forms/ha-input_datetime-form.ts index 98532d7ba0..dbe99860c0 100644 --- a/src/panels/config/helpers/forms/ha-input_datetime-form.ts +++ b/src/panels/config/helpers/forms/ha-input_datetime-form.ts @@ -1,4 +1,6 @@ import "@polymer/paper-input/paper-input"; +import "@polymer/paper-radio-button/paper-radio-button"; +import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResult, diff --git a/src/panels/config/helpers/forms/ha-input_number-form.ts b/src/panels/config/helpers/forms/ha-input_number-form.ts index c1a6340e7d..078c63768b 100644 --- a/src/panels/config/helpers/forms/ha-input_number-form.ts +++ b/src/panels/config/helpers/forms/ha-input_number-form.ts @@ -1,4 +1,6 @@ import "@polymer/paper-input/paper-input"; +import "@polymer/paper-radio-button/paper-radio-button"; +import "@polymer/paper-radio-group/paper-radio-group"; import { css, CSSResult, From fc7771ec13578c7cc0d8193d9ba267acb3022b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 15 Apr 2020 20:25:07 +0200 Subject: [PATCH 06/36] Remove npm (#5548) --- package.json | 1 - yarn.lock | 1327 ++------------------------------------------------ 2 files changed, 47 insertions(+), 1281 deletions(-) diff --git a/package.json b/package.json index bf87bfd3c5..f1a4726a5b 100644 --- a/package.json +++ b/package.json @@ -171,7 +171,6 @@ "map-stream": "^0.0.7", "merge-stream": "^1.0.1", "mocha": "^6.0.2", - "npm": "^6.14.4", "parse5": "^5.1.0", "prettier": "^2.0.4", "raw-loader": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index 324ef229ad..7e44385bea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1473,15 +1473,6 @@ dependencies: base64-js "^1.3.0" -"@iarna/cli@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-1.2.0.tgz#0f7af5e851afe895104583c4ca07377a8094d641" - integrity sha512-ukITQAqVs2n9HGmn3car/Ir7d3ta650iXhrG7pjr3EWdFmJuuOVWgYsu7ftsSe5VifEFFhjxVuX9+8F7L8hwcA== - dependencies: - signal-exit "^3.0.2" - update-notifier "^2.2.0" - yargs "^8.0.2" - "@jimp/bmp@^0.9.3": version "0.9.3" resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.9.3.tgz#98eafc81674ce750f428ac9380007f1a4e90255e" @@ -3293,15 +3284,7 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -JSONStream@^1.3.4, JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abbrev@1, abbrev@~1.1.1: +abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== @@ -3374,27 +3357,13 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -agent-base@4, agent-base@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" - integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== - dependencies: - es6-promisify "^5.0.0" - -agent-base@^4.1.0, agent-base@~4.2.1: +agent-base@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== dependencies: es6-promisify "^5.0.0" -agentkeepalive@^3.4.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" - integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== - dependencies: - humanize-ms "^1.2.1" - ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -3562,16 +3531,6 @@ ansi-wrap@0.1.0, ansi-wrap@^0.1.0: resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= -ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= - -ansistyles@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" - integrity sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk= - any-base@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" @@ -3615,16 +3574,11 @@ append-field@^1.0.0: resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= -aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -"aproba@^1.1.2 || 2", aproba@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - archiver-utils@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174" @@ -3651,7 +3605,7 @@ archiver@2.1.1: tar-stream "^1.5.0" zip-stream "^1.2.0" -archy@^1.0.0, archy@~1.0.0: +archy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= @@ -3868,7 +3822,7 @@ arrify@^1.0.0, arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -asap@^2.0.0, asap@~2.0.6: +asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -4391,18 +4345,6 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -bin-links@^1.1.2, bin-links@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.8.tgz#bd39aadab5dc4bdac222a07df5baf1af745b2228" - integrity sha512-KgmVfx+QqggqP9dA3iIc5pA4T1qEEEL+hOhOhNPaUm77OTrJoOXE/C05SJLNJe6m/2wUK7F1tDSou7n5TfCDzQ== - dependencies: - bluebird "^3.5.3" - cmd-shim "^3.0.0" - gentle-fs "^2.3.0" - graceful-fs "^4.1.15" - npm-normalize-package-bin "^1.0.0" - write-file-atomic "^2.3.0" - binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -4434,11 +4376,6 @@ blocking-elements@^0.1.0: resolved "https://registry.yarnpkg.com/blocking-elements/-/blocking-elements-0.1.0.tgz#e590b35969bb2eea571c95407e9843a80bd113a8" integrity sha512-m9UvynAHLhlWH4vSovSDAopW7DyJ91qeDnNrJqy+DE+tjhUYiXW1x7pOm3DZBczlQPPypWpOwOz5xd5A76vNvg== -bluebird@^3.5.1: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - bluebird@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" @@ -4753,11 +4690,6 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= - busboy@^0.2.11: version "0.2.14" resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" @@ -4766,16 +4698,6 @@ busboy@^0.2.11: dicer "0.2.5" readable-stream "1.1.x" -byline@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" - integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= - -byte-size@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191" - integrity sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw== - bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -4806,27 +4728,6 @@ cacache@^11.0.2, cacache@^11.3.1: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^12.0.0, cacache@^12.0.3: - version "12.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" - integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - cacache@^12.0.2: version "12.0.3" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" @@ -4863,11 +4764,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-limit@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4" - integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ== - call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -4928,7 +4824,7 @@ camelcase@^3.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= -camelcase@^4.0.0, camelcase@^4.1.0: +camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= @@ -5130,11 +5026,6 @@ chownr@^1.1.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== -chownr@^1.1.2, chownr@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -5152,13 +5043,6 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -cidr-regex@^2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-2.0.10.tgz#af13878bd4ad704de77d6dc800799358b3afa70d" - integrity sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q== - dependencies: - ip-regex "^2.1.0" - cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -5199,14 +5083,6 @@ cli-boxes@^1.0.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= -cli-columns@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e" - integrity sha1-ZzLZcpee/CrkRKHwjgj6E5yWoY4= - dependencies: - string-width "^2.0.0" - strip-ansi "^3.0.1" - cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -5221,16 +5097,6 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-table3@^0.5.0, cli-table3@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" - integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== - dependencies: - object-assign "^4.1.0" - string-width "^2.1.1" - optionalDependencies: - colors "^1.1.2" - cli-truncate@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" @@ -5315,14 +5181,6 @@ cloneable-readable@^1.0.0: process-nextick-args "^2.0.0" readable-stream "^2.3.5" -cmd-shim@^3.0.0, cmd-shim@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-3.0.3.tgz#2c35238d3df37d98ecdd7d5f6b8dc6b21cadc7cb" - integrity sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA== - dependencies: - graceful-fs "^4.1.2" - mkdirp "~0.5.0" - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -5405,11 +5263,6 @@ colornames@^1.1.1: resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" integrity sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y= -colors@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - colors@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" @@ -5423,14 +5276,6 @@ colorspace@1.1.x: color "3.0.x" text-hex "1.0.x" -columnify@~1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" - integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs= - dependencies: - strip-ansi "^3.0.0" - wcwidth "^1.0.0" - combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" @@ -5543,14 +5388,6 @@ concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" -config-chain@^1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" - integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - configstore@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" @@ -5580,7 +5417,7 @@ console-browserify@^1.1.0: dependencies: date-now "^0.1.4" -console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: +console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= @@ -5938,13 +5775,6 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@3.1.0, debug@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - debug@3.2.6, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -5959,10 +5789,12 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: dependencies: ms "^2.1.1" -debuglog@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" @@ -6036,7 +5868,7 @@ default-resolution@^2.0.0: resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ= -defaults@^1.0.2, defaults@^1.0.3: +defaults@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= @@ -6154,34 +5986,16 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" -detect-indent@~5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= - detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= - detect-node@^2.0.3, detect-node@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== -dezalgo@^1.0.0, dezalgo@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" - integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= - dependencies: - asap "^2.0.0" - wrappy "1" - diagnostics@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" @@ -6354,11 +6168,6 @@ dot-prop@^4.1.0: dependencies: is-obj "^1.0.0" -dotenv@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" - integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== - duplexer2@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" @@ -6409,11 +6218,6 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -editor@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" - integrity sha1-YMf4e9YrzGqJT6jM1q+3gjok90I= - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -6484,13 +6288,6 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= - dependencies: - iconv-lite "~0.4.13" - end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -6561,21 +6358,11 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== -env-paths@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" - integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== - env-variable@0.0.x: version "0.0.5" resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88" integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA== -err-code@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" - integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= - errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -7322,11 +7109,6 @@ fecha@^3.0.2: resolved "https://registry.yarnpkg.com/fecha/-/fecha-3.0.2.tgz#fb3adb02762ab6dd27f7d5419f2f6c21a4229cd7" integrity sha512-oJK6YbKtmz1uvuDsUHOmo9X2HKmYAcRWtzW2yrCzOJRUfyGUEu/8cDymBdedgEnkdJiTpNyPogWqfTuYffU4yA== -figgy-pudding@^3.4.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" - integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== - figgy-pudding@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" @@ -7439,11 +7221,6 @@ find-index@^0.1.1: resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" integrity sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ= -find-npm-prefix@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" - integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA== - find-parent-dir@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" @@ -7644,14 +7421,6 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -from2@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd" - integrity sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0= - dependencies: - inherits "~2.0.1" - readable-stream "~1.1.10" - from2@^2.1.0, from2@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -7698,16 +7467,7 @@ fs-mkdirp-stream@^1.0.0: graceful-fs "^4.1.11" through2 "^2.0.3" -fs-vacuum@^1.2.10, fs-vacuum@~1.2.10: - version "1.2.10" - resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" - integrity sha1-t2Kb7AekAxolSP35n17PHMizHjY= - dependencies: - graceful-fs "^4.1.2" - path-is-inside "^1.0.1" - rimraf "^2.5.2" - -fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10: +fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= @@ -7768,33 +7528,11 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -genfun@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" - integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== - gensync@^1.0.0-beta.1: version "1.0.0-beta.1" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== -gentle-fs@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.3.1.tgz#11201bf66c18f930ddca72cf69460bdfa05727b1" - integrity sha512-OlwBBwqCFPcjm33rF2BjW+Pr6/ll2741l+xooiwTCeaX2CA1ZuclavyMBe0/KlR21/XGsgY6hzEQZ15BdNa13Q== - dependencies: - aproba "^1.1.2" - chownr "^1.1.2" - cmd-shim "^3.0.3" - fs-vacuum "^1.2.10" - graceful-fs "^4.1.11" - iferr "^0.1.5" - infer-owner "^1.0.4" - mkdirp "^0.5.1" - path-is-inside "^1.0.2" - read-cmd-shim "^1.0.1" - slide "^1.1.6" - get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -7830,7 +7568,7 @@ get-stream@^3.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= -get-stream@^4.0.0, get-stream@^4.1.0: +get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== @@ -8112,11 +7850,6 @@ graceful-fs@^4.0.0, graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graceful-fs@^4.2.2, graceful-fs@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -8287,7 +8020,7 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.1.0, har-validator@~5.1.3: +har-validator@~5.1.0: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== @@ -8346,7 +8079,7 @@ has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== -has-unicode@^2.0.0, has-unicode@~2.0.1: +has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= @@ -8449,11 +8182,6 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== -hosted-git-info@^2.7.1, hosted-git-info@^2.8.8: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" @@ -8518,11 +8246,6 @@ htmlparser2@^3.3.0: inherits "^2.0.1" readable-stream "^3.1.1" -http-cache-semantics@^3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" - integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== - http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" @@ -8565,14 +8288,6 @@ http-parser-js@>=0.4.0: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8" integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w== -http-proxy-agent@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" - integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== - dependencies: - agent-base "4" - debug "3.1.0" - http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" @@ -8624,21 +8339,6 @@ https-proxy-agent@^2.2.1: agent-base "^4.1.0" debug "^3.1.0" -https-proxy-agent@^2.2.3: - version "2.2.4" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" - integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== - dependencies: - agent-base "^4.3.0" - debug "^3.1.0" - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= - dependencies: - ms "^2.0.0" - husky@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" @@ -8662,7 +8362,7 @@ iconv-lite@0.4.23: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -8679,11 +8379,6 @@ iferr@^0.1.5: resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -iferr@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-1.0.2.tgz#e9fde49a9da06dc4a4194c6c9ed6d08305037a6d" - integrity sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg== - ignore-walk@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" @@ -8764,12 +8459,12 @@ indexof@0.0.1: resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= -infer-owner@^1.0.3, infer-owner@^1.0.4: +infer-owner@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== -inflight@^1.0.4, inflight@~1.0.6: +inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= @@ -8787,7 +8482,7 @@ inherits@2.0.1: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= -inherits@2.0.4, inherits@^2.0.4: +inherits@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -8797,20 +8492,6 @@ ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== -init-package-json@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" - integrity sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw== - dependencies: - glob "^7.1.1" - npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" - promzard "^0.3.0" - read "~1.0.1" - read-package-json "1 || 2" - semver "2.x || 3.x || 4 || 5" - validate-npm-package-license "^3.0.1" - validate-npm-package-name "^3.0.0" - inquirer@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" @@ -8894,7 +8575,7 @@ ip-regex@^2.1.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= -ip@1.1.5, ip@^1.1.0, ip@^1.1.5: +ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= @@ -8987,13 +8668,6 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-cidr@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.0.tgz#72e233d8e1c4cd1d3f11713fcce3eba7b0e3476f" - integrity sha512-3kxTForpuj8O4iHn0ocsn1jxRm5VYm60GDghK6HXmpn4IyZOoRy9/GmdjFA2yEMqw91TB1/K3bFTuI7FlFNR1g== - dependencies: - cidr-regex "^2.0.10" - is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -9431,7 +9105,7 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -9511,11 +9185,6 @@ jsonminify@~0.2.3: resolved "https://registry.yarnpkg.com/jsonminify/-/jsonminify-0.2.3.tgz#4b842c8a3fe5d6aa48b2f8f95a1cf9a80c019d8e" integrity sha1-S4Qsij/l1qpIsvj5Whz5qAwBnY4= -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= - jsonschema@^1.1.0, jsonschema@^1.1.1: version "1.2.4" resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.4.tgz#a46bac5d3506a254465bc548876e267c6d0d6464" @@ -9617,11 +9286,6 @@ launchpad@^0.7.0: q "^1.4.1" underscore "^1.8.3" -lazy-property@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lazy-property/-/lazy-property-1.0.0.tgz#84ddc4b370679ba8bd4cdcfa4c06b43d57111147" - integrity sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc= - lazystream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" @@ -9685,140 +9349,6 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -libcipm@^4.0.7: - version "4.0.8" - resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.8.tgz#dcea4919e10dfbce420327e63901613b9141bc89" - integrity sha512-IN3hh2yDJQtZZ5paSV4fbvJg4aHxCCg5tcZID/dSVlTuUiWktsgaldVljJv6Z5OUlYspx6xQkbR0efNodnIrOA== - dependencies: - bin-links "^1.1.2" - bluebird "^3.5.1" - figgy-pudding "^3.5.1" - find-npm-prefix "^1.0.2" - graceful-fs "^4.1.11" - ini "^1.3.5" - lock-verify "^2.1.0" - mkdirp "^0.5.1" - npm-lifecycle "^3.0.0" - npm-logical-tree "^1.2.1" - npm-package-arg "^6.1.0" - pacote "^9.1.0" - read-package-json "^2.0.13" - rimraf "^2.6.2" - worker-farm "^1.6.0" - -libnpm@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/libnpm/-/libnpm-3.0.1.tgz#0be11b4c9dd4d1ffd7d95c786e92e55d65be77a2" - integrity sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ== - dependencies: - bin-links "^1.1.2" - bluebird "^3.5.3" - find-npm-prefix "^1.0.2" - libnpmaccess "^3.0.2" - libnpmconfig "^1.2.1" - libnpmhook "^5.0.3" - libnpmorg "^1.0.1" - libnpmpublish "^1.1.2" - libnpmsearch "^2.0.2" - libnpmteam "^1.0.2" - lock-verify "^2.0.2" - npm-lifecycle "^3.0.0" - npm-logical-tree "^1.2.1" - npm-package-arg "^6.1.0" - npm-profile "^4.0.2" - npm-registry-fetch "^4.0.0" - npmlog "^4.1.2" - pacote "^9.5.3" - read-package-json "^2.0.13" - stringify-package "^1.0.0" - -libnpmaccess@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.2.tgz#8b2d72345ba3bef90d3b4f694edd5c0417f58923" - integrity sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ== - dependencies: - aproba "^2.0.0" - get-stream "^4.0.0" - npm-package-arg "^6.1.0" - npm-registry-fetch "^4.0.0" - -libnpmconfig@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/libnpmconfig/-/libnpmconfig-1.2.1.tgz#c0c2f793a74e67d4825e5039e7a02a0044dfcbc0" - integrity sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA== - dependencies: - figgy-pudding "^3.5.1" - find-up "^3.0.0" - ini "^1.3.5" - -libnpmhook@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-5.0.3.tgz#4020c0f5edbf08ebe395325caa5ea01885b928f7" - integrity sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmorg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-1.0.1.tgz#5d2503f6ceb57f33dbdcc718e6698fea6d5ad087" - integrity sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmpublish@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.3.tgz#e3782796722d79eef1a0a22944c117e0c4ca4280" - integrity sha512-/3LsYqVc52cHXBmu26+J8Ed7sLs/hgGVFMH1mwYpL7Qaynb9RenpKqIKu0sJ130FB9PMkpMlWjlbtU8A4m7CQw== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.5.1" - get-stream "^4.0.0" - lodash.clonedeep "^4.5.0" - normalize-package-data "^2.4.0" - npm-package-arg "^6.1.0" - npm-registry-fetch "^4.0.0" - semver "^5.5.1" - ssri "^6.0.1" - -libnpmsearch@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-2.0.2.tgz#9a4f059102d38e3dd44085bdbfe5095f2a5044cf" - integrity sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg== - dependencies: - figgy-pudding "^3.5.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpmteam@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-1.0.2.tgz#8b48bcbb6ce70dd8150c950fcbdbf3feb6eec820" - integrity sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA== - dependencies: - aproba "^2.0.0" - figgy-pudding "^3.4.1" - get-stream "^4.0.0" - npm-registry-fetch "^4.0.0" - -libnpx@^10.2.2: - version "10.2.3" - resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-10.2.3.tgz#d5e01f12d383ffca9a947807ca6a8f587d38fe2c" - integrity sha512-bCvdARu55fLQBhMfcYGF0GznF1kB2sqxq/9zKZ3652M8DDFWpVpCnpgzjzn0yWMDMez5ZGMBiX24yR11uEYZVQ== - dependencies: - dotenv "^5.0.1" - npm-package-arg "^6.0.0" - rimraf "^2.6.2" - safe-buffer "^5.1.0" - update-notifier "^2.3.0" - which "^1.3.0" - y18n "^4.0.0" - yargs "^11.0.0" - liftoff@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" @@ -10029,35 +9559,6 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lock-verify@^2.0.2, lock-verify@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.0.tgz#12432feb68bb647071c78c44bde16029a0f7d935" - integrity sha512-BhM1Vqsu7x0s+EalTifNjdDPks+ZjdAhComvnA6VcCIlDOI5ouELXqAe1BYuEIP4zGN0W08xVm6byJV1LnCiJg== - dependencies: - "@iarna/cli" "^1.2.0" - npm-package-arg "^6.1.0" - semver "^5.4.1" - -lockfile@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" - integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== - dependencies: - signal-exit "^3.0.2" - -lodash._baseuniq@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" - integrity sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg= - dependencies: - lodash._createset "~4.0.0" - lodash._root "~3.0.0" - -lodash._createset@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" - integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= - lodash._escapehtmlchar@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz#df67c3bb6b7e8e1e831ab48bfa0795b92afe899d" @@ -10103,11 +9604,6 @@ lodash._reunescapedhtml@~2.4.1: lodash._htmlescapes "~2.4.1" lodash.keys "~2.4.1" -lodash._root@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= - lodash._shimkeys@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" @@ -10120,11 +9616,6 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= -lodash.clonedeep@^4.5.0, lodash.clonedeep@~4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.deburr@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/lodash.deburr/-/lodash.deburr-4.1.0.tgz#ddb1bbb3ef07458c0177ba07de14422cb033ff9b" @@ -10234,16 +9725,6 @@ lodash.templatesettings@~2.4.1: lodash._reinterpolate "~2.4.1" lodash.escape "~2.4.1" -lodash.union@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= - -lodash.uniq@~4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - lodash.values@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-2.4.1.tgz#abf514436b3cb705001627978cbcf30b1280eea4" @@ -10251,11 +9732,6 @@ lodash.values@~2.4.1: dependencies: lodash.keys "~2.4.1" -lodash.without@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" - integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw= - lodash@4.17.11, "lodash@>=3.5 <5", lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.8.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -10403,23 +9879,6 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== -make-fetch-happen@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd" - integrity sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag== - dependencies: - agentkeepalive "^3.4.1" - cacache "^12.0.0" - http-cache-semantics "^3.8.1" - http-proxy-agent "^2.1.0" - https-proxy-agent "^2.2.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - node-fetch-npm "^2.0.2" - promise-retry "^1.1.1" - socks-proxy-agent "^4.0.0" - ssri "^6.0.0" - make-iterator@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" @@ -10511,23 +9970,11 @@ mdn-polyfills@^5.16.0: resolved "https://registry.yarnpkg.com/mdn-polyfills/-/mdn-polyfills-5.17.0.tgz#462b3e34d5c6ba769a32fda2b270e711da634a05" integrity sha512-KntYq3r7jQ3lqjGvQ+1zIv6Yvlt+G3Y3TngDZqzSB7SNBjW7IZ8WyrhHM4LyLWzgUVX53DrC2XR7cymQqbTFkw== -meant@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.1.tgz#66044fea2f23230ec806fb515efea29c44d2115d" - integrity sha512-UakVLFjKkbbUwNWJ2frVLnnAtbb7D7DsloxRd3s/gDpI8rdv8W5Hp3NaDb+POBI1fQdeussER6NB8vpcRURvlg== - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= - dependencies: - mimic-fn "^1.0.0" - mem@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.2.0.tgz#5ee057680ed9cb8dad8a78d820f9a8897a102025" @@ -10775,14 +10222,6 @@ minipass@^2.2.1, minipass@^2.3.4: safe-buffer "^5.1.2" yallist "^3.0.0" -minipass@^2.3.5, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - minizlib@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" @@ -10790,13 +10229,6 @@ minizlib@^1.1.1: dependencies: minipass "^2.2.1" -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - mississippi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" @@ -10836,7 +10268,7 @@ mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: dependencies: minimist "0.0.8" -mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.0: +mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -10904,11 +10336,6 @@ ms@2.1.1, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - multer@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.1.tgz#24b12a416a22fec2ade810539184bf138720159e" @@ -10956,7 +10383,7 @@ mute-stdout@^1.0.0: resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== -mute-stream@0.0.8, mute-stream@~0.0.4: +mute-stream@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== @@ -11066,37 +10493,11 @@ node-environment-flags@1.0.4: dependencies: object.getownpropertydescriptors "^2.0.3" -node-fetch-npm@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4" - integrity sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg== - dependencies: - encoding "^0.1.11" - json-parse-better-errors "^1.0.0" - safe-buffer "^5.1.1" - node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== -node-gyp@^5.0.2, node-gyp@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.0.tgz#8e31260a7af4a2e2f994b0673d4e0b3866156332" - integrity sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.1.2" - request "^2.88.0" - rimraf "^2.6.3" - semver "^5.7.1" - tar "^4.4.12" - which "^1.3.1" - "node-libs-browser@^1.0.0 || ^2.0.0": version "2.2.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77" @@ -11212,15 +10613,7 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" -nopt@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0: +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -11249,74 +10642,11 @@ now-and-later@^2.0.0: dependencies: once "^1.3.2" -npm-audit-report@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.3.tgz#8226deeb253b55176ed147592a3995442f2179ed" - integrity sha512-8nH/JjsFfAWMvn474HB9mpmMjrnKb1Hx/oTAdjv4PT9iZBvBxiZ+wtDUapHCJwLqYGQVPaAfs+vL5+5k9QndXw== - dependencies: - cli-table3 "^0.5.0" - console-control-strings "^1.1.0" - npm-bundled@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== -npm-cache-filename@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" - integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE= - -npm-install-checks@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9" - integrity sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg== - dependencies: - semver "^2.3.0 || 3.x || 4 || 5" - -npm-lifecycle@^3.0.0, npm-lifecycle@^3.1.4: - version "3.1.5" - resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309" - integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g== - dependencies: - byline "^5.0.0" - graceful-fs "^4.1.15" - node-gyp "^5.0.2" - resolve-from "^4.0.0" - slide "^1.1.6" - uid-number "0.0.6" - umask "^1.1.0" - which "^1.3.1" - -npm-logical-tree@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz#44610141ca24664cad35d1e607176193fd8f5b88" - integrity sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg== - -npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0, npm-package-arg@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" - integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg== - dependencies: - hosted-git-info "^2.7.1" - osenv "^0.1.5" - semver "^5.6.0" - validate-npm-package-name "^3.0.0" - -npm-packlist@^1.1.12, npm-packlist@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" - integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-normalize-package-bin "^1.0.1" - npm-packlist@^1.1.6: version "1.4.1" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" @@ -11332,37 +10662,6 @@ npm-path@^2.0.2: dependencies: which "^1.2.10" -npm-pick-manifest@^3.0.0, npm-pick-manifest@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7" - integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw== - dependencies: - figgy-pudding "^3.5.1" - npm-package-arg "^6.0.0" - semver "^5.4.1" - -npm-profile@^4.0.2, npm-profile@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.4.tgz#28ee94390e936df6d084263ee2061336a6a1581b" - integrity sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ== - dependencies: - aproba "^1.1.2 || 2" - figgy-pudding "^3.4.1" - npm-registry-fetch "^4.0.0" - -npm-registry-fetch@^4.0.0, npm-registry-fetch@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.3.tgz#3c2179e39e04f9348b1c2979545951d36bee8766" - integrity sha512-WGvUx0lkKFhu9MbiGFuT9nG2NpfQ+4dCJwRwwtK2HK5izJEvwDxMeUyqbuMS7N/OkpVCqDorV6rO5E4V9F8lJw== - dependencies: - JSONStream "^1.3.4" - bluebird "^3.5.1" - figgy-pudding "^3.4.1" - lru-cache "^5.1.1" - make-fetch-happen "^5.0.0" - npm-package-arg "^6.1.0" - safe-buffer "^5.2.0" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -11370,11 +10669,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-user-validate@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.0.tgz#8ceca0f5cea04d4e93519ef72d0557a75122e951" - integrity sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE= - npm-which@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" @@ -11384,128 +10678,7 @@ npm-which@^3.0.1: npm-path "^2.0.2" which "^1.2.10" -npm@^6.14.4: - version "6.14.4" - resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.4.tgz#50a1c6274fb451ca18f6ff472d2a73f006adbd66" - integrity sha512-B8UDDbWvdkW6RgXFn8/h2cHJP/u/FPa4HWeGzW23aNEBARN3QPrRaHqPIZW2NSN3fW649gtgUDNZpaRs0zTMPw== - dependencies: - JSONStream "^1.3.5" - abbrev "~1.1.1" - ansicolors "~0.3.2" - ansistyles "~0.1.3" - aproba "^2.0.0" - archy "~1.0.0" - bin-links "^1.1.7" - bluebird "^3.5.5" - byte-size "^5.0.1" - cacache "^12.0.3" - call-limit "^1.1.1" - chownr "^1.1.4" - ci-info "^2.0.0" - cli-columns "^3.1.2" - cli-table3 "^0.5.1" - cmd-shim "^3.0.3" - columnify "~1.5.4" - config-chain "^1.1.12" - detect-indent "~5.0.0" - detect-newline "^2.1.0" - dezalgo "~1.0.3" - editor "~1.0.0" - figgy-pudding "^3.5.1" - find-npm-prefix "^1.0.2" - fs-vacuum "~1.2.10" - fs-write-stream-atomic "~1.0.10" - gentle-fs "^2.3.0" - glob "^7.1.6" - graceful-fs "^4.2.3" - has-unicode "~2.0.1" - hosted-git-info "^2.8.8" - iferr "^1.0.2" - infer-owner "^1.0.4" - inflight "~1.0.6" - inherits "^2.0.4" - ini "^1.3.5" - init-package-json "^1.10.3" - is-cidr "^3.0.0" - json-parse-better-errors "^1.0.2" - lazy-property "~1.0.0" - libcipm "^4.0.7" - libnpm "^3.0.1" - libnpmaccess "^3.0.2" - libnpmhook "^5.0.3" - libnpmorg "^1.0.1" - libnpmsearch "^2.0.2" - libnpmteam "^1.0.2" - libnpx "^10.2.2" - lock-verify "^2.1.0" - lockfile "^1.0.4" - lodash._baseuniq "~4.6.0" - lodash.clonedeep "~4.5.0" - lodash.union "~4.6.0" - lodash.uniq "~4.5.0" - lodash.without "~4.4.0" - lru-cache "^5.1.1" - meant "~1.0.1" - mississippi "^3.0.0" - mkdirp "^0.5.4" - move-concurrently "^1.0.1" - node-gyp "^5.1.0" - nopt "~4.0.1" - normalize-package-data "^2.5.0" - npm-audit-report "^1.3.2" - npm-cache-filename "~1.0.2" - npm-install-checks "^3.0.2" - npm-lifecycle "^3.1.4" - npm-package-arg "^6.1.1" - npm-packlist "^1.4.8" - npm-pick-manifest "^3.0.2" - npm-profile "^4.0.4" - npm-registry-fetch "^4.0.3" - npm-user-validate "~1.0.0" - npmlog "~4.1.2" - once "~1.4.0" - opener "^1.5.1" - osenv "^0.1.5" - pacote "^9.5.12" - path-is-inside "~1.0.2" - promise-inflight "~1.0.1" - qrcode-terminal "^0.12.0" - query-string "^6.8.2" - qw "~1.0.1" - read "~1.0.7" - read-cmd-shim "^1.0.5" - read-installed "~4.0.3" - read-package-json "^2.1.1" - read-package-tree "^5.3.1" - readable-stream "^3.6.0" - readdir-scoped-modules "^1.1.0" - request "^2.88.0" - retry "^0.12.0" - rimraf "^2.7.1" - safe-buffer "^5.1.2" - semver "^5.7.1" - sha "^3.0.0" - slide "~1.1.6" - sorted-object "~2.0.1" - sorted-union-stream "~2.1.3" - ssri "^6.0.1" - stringify-package "^1.0.1" - tar "^4.4.13" - text-table "~0.2.0" - tiny-relative-date "^1.3.0" - uid-number "0.0.6" - umask "~1.1.0" - unique-filename "^1.1.1" - unpipe "~1.0.0" - update-notifier "^2.5.0" - uuid "^3.3.3" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "~3.0.0" - which "^1.3.1" - worker-farm "^1.7.0" - write-file-atomic "^2.4.3" - -npmlog@^4.0.2, npmlog@^4.1.2, npmlog@~4.1.2: +npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -11694,7 +10867,7 @@ on-headers@~1.0.2: resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0, once@~1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -11720,11 +10893,6 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -opener@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" - integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== - opn@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/opn/-/opn-3.0.3.tgz#b6d99e7399f78d65c3baaffef1fb288e9b85243a" @@ -11798,15 +10966,6 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - os-locale@^3.0.0, os-locale@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" @@ -11821,7 +10980,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.3, osenv@^0.1.4, osenv@^0.1.5: +osenv@^0.1.3, osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -11909,42 +11068,6 @@ package-json@^4.0.0: registry-url "^3.0.3" semver "^5.1.0" -pacote@^9.1.0, pacote@^9.5.12, pacote@^9.5.3: - version "9.5.12" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66" - integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ== - dependencies: - bluebird "^3.5.3" - cacache "^12.0.2" - chownr "^1.1.2" - figgy-pudding "^3.5.1" - get-stream "^4.1.0" - glob "^7.1.3" - infer-owner "^1.0.4" - lru-cache "^5.1.1" - make-fetch-happen "^5.0.0" - minimatch "^3.0.4" - minipass "^2.3.5" - mississippi "^3.0.0" - mkdirp "^0.5.1" - normalize-package-data "^2.4.0" - npm-normalize-package-bin "^1.0.0" - npm-package-arg "^6.1.0" - npm-packlist "^1.1.12" - npm-pick-manifest "^3.0.0" - npm-registry-fetch "^4.0.0" - osenv "^0.1.5" - promise-inflight "^1.0.1" - promise-retry "^1.1.1" - protoduck "^5.0.1" - rimraf "^2.6.2" - safe-buffer "^5.1.2" - semver "^5.6.0" - ssri "^6.0.1" - tar "^4.4.10" - unique-filename "^1.1.1" - which "^1.3.1" - pako@^1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -12140,7 +11263,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -12670,19 +11793,11 @@ progress@2.0.3, progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -promise-inflight@^1.0.1, promise-inflight@~1.0.1: +promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -promise-retry@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" - integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0= - dependencies: - err-code "^1.0.0" - retry "^0.10.0" - promise@^8.0.1: version "8.0.3" resolved "https://registry.yarnpkg.com/promise/-/promise-8.0.3.tgz#f592e099c6cddc000d538ee7283bb190452b0bf6" @@ -12690,13 +11805,6 @@ promise@^8.0.1: dependencies: asap "~2.0.6" -promzard@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" - integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= - dependencies: - read "1" - prop-types-extra@^1.0.1, prop-types-extra@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.0.tgz#32609910ea2dcf190366bacd3490d5a6412a605f" @@ -12719,18 +11827,6 @@ property-expr@^1.5.0: resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-1.5.1.tgz#22e8706894a0c8e28d58735804f6ba3a3673314f" integrity sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g== -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - -protoduck@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" - integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== - dependencies: - genfun "^5.0.0" - proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" @@ -12762,11 +11858,6 @@ psl@^1.1.24: resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" @@ -12809,7 +11900,7 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@2.x.x, punycode@^2.1.0, punycode@^2.1.1: +punycode@2.x.x, punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -12829,11 +11920,6 @@ q@^1.4.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qrcode-terminal@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" - integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== - qs@6.5.2, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -12844,15 +11930,6 @@ qs@6.7.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -query-string@^6.8.2: - version "6.12.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.12.1.tgz#2ae4d272db4fba267141665374e49a1de09e8a7c" - integrity sha512-OHj+zzfRMyj3rmo/6G8a5Ifvw3AleL/EbcHMD27YA31Q+cO5lfmQxECkImuNVjcskLcvBRVHNAB3w6udMs1eAA== - dependencies: - decode-uri-component "^0.2.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -12868,11 +11945,6 @@ querystringify@^2.0.0: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== -qw@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.1.tgz#efbfdc740f9ad054304426acb183412cc8b996d4" - integrity sha1-77/cdA+a0FQwRCassYNBLMi5ltQ= - ramda@^0.26.1: version "0.26.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" @@ -13000,48 +12072,6 @@ react-transition-group@^2.2.0: prop-types "^15.6.2" react-lifecycles-compat "^3.0.4" -read-cmd-shim@^1.0.1, read-cmd-shim@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" - integrity sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA== - dependencies: - graceful-fs "^4.1.2" - -read-installed@~4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" - integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc= - dependencies: - debuglog "^1.0.1" - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - semver "2 || 3 || 4 || 5" - slide "~1.1.3" - util-extend "^1.0.1" - optionalDependencies: - graceful-fs "^4.1.2" - -"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.13, read-package-json@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.1.tgz#16aa66c59e7d4dad6288f179dd9295fd59bb98f1" - integrity sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A== - dependencies: - glob "^7.1.1" - json-parse-better-errors "^1.0.1" - normalize-package-data "^2.0.0" - npm-normalize-package-bin "^1.0.0" - optionalDependencies: - graceful-fs "^4.1.2" - -read-package-tree@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636" - integrity sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw== - dependencies: - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - util-promisify "^2.1.0" - read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -13085,13 +12115,6 @@ read-pkg@^4.0.1: parse-json "^4.0.0" pify "^3.0.0" -read@1, read@~1.0.1, read@~1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= - dependencies: - mute-stream "~0.0.4" - "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -13105,7 +12128,7 @@ read@1, read@~1.0.1, read@~1.0.7: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@1.1.x, readable-stream@^1.0.26-2, readable-stream@^1.0.26-4, readable-stream@~1.1.10, readable-stream@~1.1.9: +readable-stream@1.1.x, readable-stream@^1.0.26-2, readable-stream@^1.0.26-4, readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= @@ -13134,25 +12157,6 @@ readable-stream@1.1.x, readable-stream@^1.0.26-2, readable-stream@^1.0.26-4, rea isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" - integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - graceful-fs "^4.1.2" - once "^1.3.0" - readdirp@^2.0.0, readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -13450,32 +12454,6 @@ request@2.88.0, request@^2.85.0: tunnel-agent "^0.6.0" uuid "^3.3.2" -request@^2.88.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-dir@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/require-dir/-/require-dir-1.2.0.tgz#0d443b75e96012d3ca749cf19f529a789ae74817" @@ -13593,11 +12571,6 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" - integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= - retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -13615,7 +12588,7 @@ rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: dependencies: glob "^7.1.3" -rimraf@^2.5.2, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -13692,11 +12665,6 @@ safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -13802,16 +12770,16 @@ semver-greatest-satisfied-range@^1.1.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== -"semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.5.1, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -13956,13 +12924,6 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -sha@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/sha/-/sha-3.0.0.tgz#b2f2f90af690c16a3a839a6a6c680ea51fedd1ae" - integrity sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw== - dependencies: - graceful-fs "^4.1.2" - shady-css-parser@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/shady-css-parser/-/shady-css-parser-0.1.0.tgz#534dc79c8ca5884c5ed92a4e5a13d6d863bca428" @@ -14082,16 +13043,6 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -slide@^1.1.6, slide@~1.1.3, slide@~1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= - -smart-buffer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" - integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -14188,35 +13139,6 @@ sockjs@0.3.19: faye-websocket "^0.10.0" uuid "^3.0.1" -socks-proxy-agent@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" - integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== - dependencies: - agent-base "~4.2.1" - socks "~2.3.2" - -socks@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" - integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== - dependencies: - ip "1.1.5" - smart-buffer "^4.1.0" - -sorted-object@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" - integrity sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw= - -sorted-union-stream@~2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz#c7794c7e077880052ff71a8d4a2dbb4a9a638ac7" - integrity sha1-x3lMfgd4gAUv9xqNSi27Sppjisc= - dependencies: - from2 "^1.3.0" - stream-iterate "^1.1.0" - source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -14343,11 +13265,6 @@ spdy@^4.0.1: select-hose "^2.0.0" spdy-transport "^3.0.0" -split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -14375,7 +13292,7 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -ssri@^6.0.0, ssri@^6.0.1: +ssri@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== @@ -14460,14 +13377,6 @@ stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" -stream-iterate@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/stream-iterate/-/stream-iterate-1.2.0.tgz#2bd7c77296c1702a46488b8ad41f79865eecd4e1" - integrity sha1-K9fHcpbBcCpGSIuK1B95hl7s1OE= - dependencies: - readable-stream "^2.1.5" - stream-shift "^1.0.0" - stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" @@ -14499,11 +13408,6 @@ streamsearch@0.1.2: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= -strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= - string-argv@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" @@ -14618,11 +13522,6 @@ stringify-object@^3.2.2, stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -stringify-package@^1.0.0, stringify-package@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" - integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg== - strip-ansi@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" @@ -14886,19 +13785,6 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" -tar@^4.4.10, tar@^4.4.12, tar@^4.4.13: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - temp@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" @@ -14981,7 +13867,7 @@ text-hex@1.0.x: resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== -text-table@^0.2.0, text-table@~0.2.0: +text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= @@ -15047,7 +13933,7 @@ through2@^3.0.0: dependencies: readable-stream "2 || 3" -"through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8, through@~2.3.6: +through@^2.3.6, through@^2.3.8, through@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -15079,11 +13965,6 @@ timm@^1.6.1: resolved "https://registry.yarnpkg.com/timm/-/timm-1.6.2.tgz#dfd8c6719f7ba1fcfc6295a32670a1c6d166c0bd" integrity sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw== -tiny-relative-date@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" - integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A== - tinycolor2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" @@ -15205,14 +14086,6 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -15381,16 +14254,6 @@ uglify-js@3.4.x: commander "~2.19.0" source-map "~0.6.1" -uid-number@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= - -umask@^1.1.0, umask@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" - integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= - unc-path-regex@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" @@ -15540,7 +14403,7 @@ upath@^1.1.1: resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== -update-notifier@^2.2.0, update-notifier@^2.3.0, update-notifier@^2.5.0: +update-notifier@^2.2.0, update-notifier@^2.3.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== @@ -15623,18 +14486,6 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util-extend@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" - integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= - -util-promisify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53" - integrity sha1-PCI2R2xNMsX/PEcAKt18E7moKlM= - dependencies: - object.getownpropertydescriptors "^2.0.3" - util.promisify@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" @@ -15672,11 +14523,6 @@ uuid@^3.0.1, uuid@^3.2.1, uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== -uuid@^3.3.3: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - v8-compile-cache@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" @@ -15708,7 +14554,7 @@ validate-element-name@^2.1.1: log-symbols "^1.0.0" meow "^3.7.0" -validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: +validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== @@ -15716,13 +14562,6 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= - dependencies: - builtins "^1.0.3" - value-or-function@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" @@ -15963,13 +14802,6 @@ wct-sauce@^2.0.2: temp "^0.8.1" uuid "^3.2.1" -wcwidth@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - wd@^1.2.0: version "1.11.1" resolved "https://registry.yarnpkg.com/wd/-/wd-1.11.1.tgz#21a33e21977ad20522bb189f6529c3b55ac3862c" @@ -16198,7 +15030,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1.3.1, which@^1.0.8, which@^1.2.10, which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: +which@1.3.1, which@^1.0.8, which@^1.2.10, which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -16407,7 +15239,7 @@ worker-farm@^1.5.2: dependencies: errno "~0.1.7" -worker-farm@^1.6.0, worker-farm@^1.7.0: +worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== @@ -16460,15 +15292,6 @@ write-file-atomic@^2.0.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" -write-file-atomic@^2.3.0, write-file-atomic@^2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - write@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" @@ -16583,11 +15406,6 @@ yallist@^3.0.0, yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== -yallist@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yargs-parser@11.1.1, yargs-parser@^11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" @@ -16611,20 +15429,6 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= - dependencies: - camelcase "^4.1.0" - -yargs-parser@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" - integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= - dependencies: - camelcase "^4.1.0" - yargs-unparser@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" @@ -16669,24 +15473,6 @@ yargs@13.2.4: y18n "^4.0.0" yargs-parser "^13.1.0" -yargs@^11.0.0: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.1.tgz#5052efe3446a4df5ed669c995886cc0f13702766" - integrity sha512-PRU7gJrJaXv3q3yQZ/+/X6KBswZiaQ+zOmdprZcouPYtQgvNU35i+68M4b1ZHLZtYFT5QObFLV+ZkmJYcwKdiw== - dependencies: - cliui "^4.0.0" - decamelize "^1.1.1" - find-up "^2.1.0" - get-caller-file "^1.0.1" - os-locale "^3.1.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^9.0.2" - yargs@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" @@ -16706,25 +15492,6 @@ yargs@^7.1.0: y18n "^3.2.1" yargs-parser "^5.0.0" -yargs@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" - integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A= - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" From ba0cba1a2b013d9cb7196f6203b4bd6d8f6d475c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 15 Apr 2020 11:47:29 -0700 Subject: [PATCH 07/36] Update where we load integration titles from (#5546) --- src/components/ha-related-items.ts | 2 +- src/data/config_flow.ts | 2 +- .../dialog-config-entry-system-options.ts | 4 ++-- src/dialogs/config-flow/show-dialog-config-flow.ts | 4 ++-- src/dialogs/config-flow/step-flow-pick-handler.ts | 3 +-- src/onboarding/onboarding-integrations.ts | 4 +--- src/panels/config/devices/ha-config-devices-dashboard.ts | 5 ++--- src/panels/config/devices/ha-devices-data-table.ts | 5 ++--- src/panels/config/entities/ha-config-entities.ts | 4 ++-- .../config/integrations/ha-config-entries-dashboard.ts | 6 +++--- 10 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/components/ha-related-items.ts b/src/components/ha-related-items.ts index 124c93404e..6077f0c284 100644 --- a/src/components/ha-related-items.ts +++ b/src/components/ha-related-items.ts @@ -98,7 +98,7 @@ export class HaRelatedItems extends SubscribeMixin(LitElement) { href="/config/integrations/config_entry/${relatedConfigEntryId}" @click=${this._close} > - ${this.hass.localize(`component.${entry.domain}.config.title`)}: + ${this.hass.localize(`component.${entry.domain}.title`)}: ${entry.title} `; diff --git a/src/data/config_flow.ts b/src/data/config_flow.ts index 268e3e04ae..288803a715 100644 --- a/src/data/config_flow.ts +++ b/src/data/config_flow.ts @@ -75,7 +75,7 @@ export const localizeConfigFlowTitle = ( const placeholders = flow.context.title_placeholders || {}; const placeholderKeys = Object.keys(placeholders); if (placeholderKeys.length === 0) { - return localize(`component.${flow.handler}.config.title`); + return localize(`component.${flow.handler}.title`); } const args: string[] = []; placeholderKeys.forEach((key) => { diff --git a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts index bd4270ca67..5ee5bfd538 100644 --- a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts +++ b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts @@ -66,7 +66,7 @@ class DialogConfigEntrySystemOptions extends LitElement { "ui.dialogs.config_entry_system_options.title", "integration", this.hass.localize( - `component.${this._params.entry.domain}.config.title` + `component.${this._params.entry.domain}.title` ) || this._params.entry.domain )} @@ -98,7 +98,7 @@ class DialogConfigEntrySystemOptions extends LitElement { "ui.dialogs.config_entry_system_options.enable_new_entities_description", "integration", this.hass.localize( - `component.${this._params.entry.domain}.config.title` + `component.${this._params.entry.domain}.title` ) || this._params.entry.domain )}

diff --git a/src/dialogs/config-flow/show-dialog-config-flow.ts b/src/dialogs/config-flow/show-dialog-config-flow.ts index 5a044a2239..0a2d6341e2 100644 --- a/src/dialogs/config-flow/show-dialog-config-flow.ts +++ b/src/dialogs/config-flow/show-dialog-config-flow.ts @@ -26,8 +26,8 @@ export const showConfigFlowDialog = ( getConfigFlowHandlers(hass).then((handlers) => handlers.sort((handlerA, handlerB) => caseInsensitiveCompare( - hass.localize(`component.${handlerA}.config.title`), - hass.localize(`component.${handlerB}.config.title`) + hass.localize(`component.${handlerA}.title`), + hass.localize(`component.${handlerB}.title`) ) ) ), diff --git a/src/dialogs/config-flow/step-flow-pick-handler.ts b/src/dialogs/config-flow/step-flow-pick-handler.ts index c6bee2c316..804732b78a 100644 --- a/src/dialogs/config-flow/step-flow-pick-handler.ts +++ b/src/dialogs/config-flow/step-flow-pick-handler.ts @@ -43,8 +43,7 @@ class StepFlowPickHandler extends LitElement { private _getHandlers = memoizeOne((h: string[], filter?: string) => { const handlers: HandlerObj[] = h.map((handler) => { return { - name: - this.hass.localize(`component.${handler}.config.title`) || handler, + name: this.hass.localize(`component.${handler}.title`) || handler, slug: handler, }; }); diff --git a/src/onboarding/onboarding-integrations.ts b/src/onboarding/onboarding-integrations.ts index 4ee2639e55..74a2d2da65 100644 --- a/src/onboarding/onboarding-integrations.ts +++ b/src/onboarding/onboarding-integrations.ts @@ -62,9 +62,7 @@ class OnboardingIntegrations extends LitElement { // Render discovered and existing entries together sorted by localized title. const entries: Array<[string, TemplateResult]> = this._entries.map( (entry) => { - const title = this.hass.localize( - `component.${entry.domain}.config.title` - ); + const title = this.hass.localize(`component.${entry.domain}.title`); return [ title, html` diff --git a/src/panels/config/devices/ha-config-devices-dashboard.ts b/src/panels/config/devices/ha-config-devices-dashboard.ts index 885873e253..a89a036a77 100644 --- a/src/panels/config/devices/ha-config-devices-dashboard.ts +++ b/src/panels/config/devices/ha-config-devices-dashboard.ts @@ -115,9 +115,8 @@ export class HaConfigDeviceDashboard extends LitElement { .filter((entId) => entId in entryLookup) .map( (entId) => - localize( - `component.${entryLookup[entId].domain}.config.title` - ) || entryLookup[entId].domain + localize(`component.${entryLookup[entId].domain}.title`) || + entryLookup[entId].domain ) .join(", ") : "No integration", diff --git a/src/panels/config/devices/ha-devices-data-table.ts b/src/panels/config/devices/ha-devices-data-table.ts index e0ab9b78b8..cbe8cd7e69 100644 --- a/src/panels/config/devices/ha-devices-data-table.ts +++ b/src/panels/config/devices/ha-devices-data-table.ts @@ -116,9 +116,8 @@ export class HaDevicesDataTable extends LitElement { .filter((entId) => entId in entryLookup) .map( (entId) => - localize( - `component.${entryLookup[entId].domain}.config.title` - ) || entryLookup[entId].domain + localize(`component.${entryLookup[entId].domain}.title`) || + entryLookup[entId].domain ) .join(", ") : "No integration", diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index f9c793bb8b..75fcdfe1f6 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -166,7 +166,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { return html` ${name}
${entity.entity_id} | - ${this.hass.localize(`component.${entity.platform}.config.title`) || + ${this.hass.localize(`component.${entity.platform}.title`) || entity.platform} `; }; @@ -190,7 +190,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { filterable: true, width: "20%", template: (platform) => - this.hass.localize(`component.${platform}.config.title`) || platform, + this.hass.localize(`component.${platform}.title`) || platform, }; columns.status = statusColumn; diff --git a/src/panels/config/integrations/ha-config-entries-dashboard.ts b/src/panels/config/integrations/ha-config-entries-dashboard.ts index 2d1efda9c7..2fac604f49 100644 --- a/src/panels/config/integrations/ha-config-entries-dashboard.ts +++ b/src/panels/config/integrations/ha-config-entries-dashboard.ts @@ -126,7 +126,7 @@ export class HaConfigManagerDashboard extends LitElement { ${this.hass.localize( - `component.${item.domain}.config.title` + `component.${item.domain}.title` )}
${this.hass.localize( - `component.${item.domain}.config.title` + `component.${item.domain}.title` )}: ${item.title}
@@ -311,7 +311,7 @@ export class HaConfigManagerDashboard extends LitElement { title: this.hass!.localize( "ui.panel.config.integrations.ignore.confirm_delete_ignore_title", "name", - this.hass.localize(`component.${entry.domain}.config.title`) + this.hass.localize(`component.${entry.domain}.title`) ), text: this.hass!.localize( "ui.panel.config.integrations.ignore.confirm_delete_ignore" From ff81536463fd417d2e51267c866fae22a7740522 Mon Sep 17 00:00:00 2001 From: Aidan Timson Date: Wed, 15 Apr 2020 19:54:01 +0100 Subject: [PATCH 08/36] Add loading for initial state on graph (#5448) * Fix type * Add loading spinner for initial state * Move to better position * Make var not a property * Make spinner same height as graph * Fix size * Make spinner centered * Adjust spinner position * Remove boolean and make no state history match height * Merge * eslint * Fix value Co-Authored-By: Bram Kragten * Commit suggestion Co-Authored-By: Bram Kragten * Suggested change Co-authored-by: Bram Kragten --- .../common/graph/get-history-coordinates.ts | 8 +++-- .../header-footer/hui-graph-header-footer.ts | 32 ++++++++++++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/panels/lovelace/common/graph/get-history-coordinates.ts b/src/panels/lovelace/common/graph/get-history-coordinates.ts index 9e0d2ba864..a8d08cf4ca 100644 --- a/src/panels/lovelace/common/graph/get-history-coordinates.ts +++ b/src/panels/lovelace/common/graph/get-history-coordinates.ts @@ -7,7 +7,7 @@ export const getHistoryCoordinates = async ( entity: string, hours: number, detail: number -): Promise => { +): Promise => { const endTime = new Date(); const startTime = new Date(); startTime.setHours(endTime.getHours() - hours); @@ -15,10 +15,14 @@ export const getHistoryCoordinates = async ( const stateHistory = await fetchRecent(hass, entity, startTime, endTime); if (stateHistory.length < 1 || stateHistory[0].length < 1) { - return undefined; + return []; } const coords = coordinates(stateHistory[0], hours, 500, detail); + if (!coords) { + return []; + } + return coords; }; diff --git a/src/panels/lovelace/header-footer/hui-graph-header-footer.ts b/src/panels/lovelace/header-footer/hui-graph-header-footer.ts index 572065d2a6..b82616ba61 100644 --- a/src/panels/lovelace/header-footer/hui-graph-header-footer.ts +++ b/src/panels/lovelace/header-footer/hui-graph-header-footer.ts @@ -10,6 +10,8 @@ import { } from "lit-element"; import { HomeAssistant } from "../../../types"; import { getHistoryCoordinates } from "../common/graph/get-history-coordinates"; + +import "@polymer/paper-spinner/paper-spinner"; import "../components/hui-graph-base"; import { LovelaceHeaderFooter } from "../types"; import { GraphHeaderFooterConfig } from "./types"; @@ -27,7 +29,7 @@ export class HuiGraphHeaderFooter extends LitElement @property() protected _config?: GraphHeaderFooterConfig; - @property() private _coordinates?: any; + @property() private _coordinates?: number[][]; private _date?: Date; @@ -60,8 +62,18 @@ export class HuiGraphHeaderFooter extends LitElement if (!this._coordinates) { return html` -
- No state history found. +
+ +
+ `; + } + + if (this._coordinates.length < 1) { + return html` +
+
+ No state history found. +
`; } @@ -100,9 +112,19 @@ export class HuiGraphHeaderFooter extends LitElement static get styles(): CSSResult { return css` + paper-spinner { + position: absolute; + top: calc(50% - 28px); + } + .container { + display: flex; + justify-content: center; + position: relative; + padding-bottom: 20%; + } .info { - text-align: center; - line-height: 58px; + position: absolute; + top: calc(50% - 16px); color: var(--secondary-text-color); } `; From 66f33ad49771aebdb2d41341728fa36ba59f3fd3 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 15 Apr 2020 13:36:25 -0700 Subject: [PATCH 09/36] Use manfiests to render doc urls (#5549) * Use manfiests to render doc urls * Update UI --- src/data/integration.ts | 26 ++++- src/data/system_log.ts | 2 + .../developer-tools/info/integrations-card.ts | 103 ++++++++++++------ .../logs/dialog-system-log-detail.ts | 62 ++++++++--- 4 files changed, 143 insertions(+), 50 deletions(-) diff --git a/src/data/integration.ts b/src/data/integration.ts index f322e96f10..7607bd3dcb 100644 --- a/src/data/integration.ts +++ b/src/data/integration.ts @@ -1,10 +1,32 @@ import { LocalizeFunc } from "../common/translations/localize"; +import { HomeAssistant } from "../types"; -export const integrationDocsUrl = (domain: string) => - `https://www.home-assistant.io/integrations/${domain}`; +export interface IntegrationManifest { + is_built_in: boolean; + domain: string; + name: string; + config_flow: boolean; + documentation: string; + dependencies?: string[]; + after_dependencies?: string[]; + codeowners?: string[]; + requirements?: string[]; + ssdp?: Array<{ manufacturer?: string; modelName?: string; st?: string }>; + zeroconf?: string[]; + homekit?: { models: string[] }; + quality_scale?: string; +} export const integrationIssuesUrl = (domain: string) => `https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+${domain}%22`; export const domainToName = (localize: LocalizeFunc, domain: string) => localize(`domain.${domain}`) || domain; + +export const fetchIntegrationManifests = (hass: HomeAssistant) => + hass.callWS({ type: "manifest/list" }); + +export const fetchIntegrationManifest = ( + hass: HomeAssistant, + integration: string +) => hass.callWS({ type: "manifest/get", integration }); diff --git a/src/data/system_log.ts b/src/data/system_log.ts index 9257c31080..865558ebb9 100644 --- a/src/data/system_log.ts +++ b/src/data/system_log.ts @@ -19,4 +19,6 @@ export const fetchSystemLog = (hass: HomeAssistant) => export const getLoggedErrorIntegration = (item: LoggedError) => item.name.startsWith("homeassistant.components.") ? item.name.split(".")[2] + : item.name.startsWith("custom_components.") + ? item.name.split(".")[1] : undefined; diff --git a/src/panels/developer-tools/info/integrations-card.ts b/src/panels/developer-tools/info/integrations-card.ts index f01d5d5d89..12b6e29f59 100644 --- a/src/panels/developer-tools/info/integrations-card.ts +++ b/src/panels/developer-tools/info/integrations-card.ts @@ -9,8 +9,9 @@ import { } from "lit-element"; import memoizeOne from "memoize-one"; import { - integrationDocsUrl, integrationIssuesUrl, + IntegrationManifest, + fetchIntegrationManifests, } from "../../../data/integration"; import { HomeAssistant } from "../../../types"; @@ -18,46 +19,67 @@ import { HomeAssistant } from "../../../types"; class IntegrationsCard extends LitElement { @property() public hass!: HomeAssistant; + @property() private _manifests?: { [domain: string]: IntegrationManifest }; + private _sortedIntegrations = memoizeOne((components: string[]) => { return components.filter((comp) => !comp.includes(".")).sort(); }); + firstUpdated(changedProps) { + super.firstUpdated(changedProps); + this._fetchManifests(); + } + protected render(): TemplateResult { return html` ${this._sortedIntegrations(this.hass!.config.components).map( - (domain) => html` - - - - - - - ` + (domain) => { + const manifest = this._manifests && this._manifests[domain]; + return html` + + + + ${!manifest + ? "" + : html` + + ${!manifest.is_built_in + ? "" + : html` + + `} + `} + + `; + } )}
- - ${domain} - - Documentation - - - - Issues - -
+ + + ${manifest?.name}
+ ${domain} +
+ + Documentation + + + + Issues + +
@@ -65,19 +87,32 @@ class IntegrationsCard extends LitElement { `; } + private async _fetchManifests() { + const manifests = {}; + for (const manifest of await fetchIntegrationManifests(this.hass)) { + manifests[manifest.domain] = manifest; + } + this._manifests = manifests; + } + static get styles(): CSSResult { return css` td { - line-height: 2em; padding: 0 8px; } td:first-child { padding-left: 0; } + td.name { + padding: 8px; + } + .domain { + color: var(--secondary-text-color); + } img { display: block; - max-height: 24px; - max-width: 24px; + max-height: 40px; + max-width: 40px; } a { color: var(--primary-color); diff --git a/src/panels/developer-tools/logs/dialog-system-log-detail.ts b/src/panels/developer-tools/logs/dialog-system-log-detail.ts index c9b54b6943..255884558a 100644 --- a/src/panels/developer-tools/logs/dialog-system-log-detail.ts +++ b/src/panels/developer-tools/logs/dialog-system-log-detail.ts @@ -10,8 +10,9 @@ import { import "../../../components/dialog/ha-paper-dialog"; import { domainToName, - integrationDocsUrl, integrationIssuesUrl, + IntegrationManifest, + fetchIntegrationManifest, } from "../../../data/integration"; import { getLoggedErrorIntegration } from "../../../data/system_log"; import { PolymerChangedEvent } from "../../../polymer-types"; @@ -25,11 +26,25 @@ class DialogSystemLogDetail extends LitElement { @property() private _params?: SystemLogDetailDialogParams; + @property() private _manifest?: IntegrationManifest; + public async showDialog(params: SystemLogDetailDialogParams): Promise { this._params = params; + this._manifest = undefined; await this.updateComplete; } + protected updated(changedProps) { + super.updated(changedProps); + if (!changedProps.has("_params") || !this._params) { + return; + } + const integration = getLoggedErrorIntegration(this._params.item); + if (integration) { + this._fetchManifest(integration); + } + } + protected render(): TemplateResult { if (!this._params) { return html``; @@ -58,19 +73,30 @@ class DialogSystemLogDetail extends LitElement { ${integration ? html`
- Integration: ${domainToName(this.hass.localize, integration)} - (documentation, - issues) + Integration: + ${this._manifest + ? this._manifest.name + : domainToName(this.hass.localize, integration)} + ${!this._manifest || + // Can happen with custom integrations + !this._manifest.documentation + ? "" + : html` + (documentation${!this._manifest.is_built_in + ? "" + : html`, + issues`}) + `} ` : ""}
@@ -100,6 +126,14 @@ class DialogSystemLogDetail extends LitElement { `; } + private async _fetchManifest(integration: string) { + try { + this._manifest = await fetchIntegrationManifest(this.hass, integration); + } catch (err) { + // Ignore if loading manifest fails. Probably bad JSON in manifest + } + } + private _openedChanged(ev: PolymerChangedEvent): void { if (!(ev.detail as any).value) { this._params = undefined; From 492e4d2df43795cc2dbadb2b9110fe0e32bc4e33 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Thu, 16 Apr 2020 00:32:44 +0000 Subject: [PATCH 10/36] [ci skip] Translation update --- translations/en.json | 7 +++++-- translations/fr.json | 42 +++++++++++++++++++-------------------- translations/it.json | 47 +++++++++++++++++++++++++++++++++++++++++++- translations/nb.json | 4 ++++ translations/pl.json | 14 ++++++------- translations/ru.json | 2 +- 6 files changed, 84 insertions(+), 32 deletions(-) diff --git a/translations/en.json b/translations/en.json index e9696a5ed7..241dbd4a00 100644 --- a/translations/en.json +++ b/translations/en.json @@ -758,11 +758,13 @@ "buttons": { "add": "Add Devices", "reconfigure": "Reconfigure Device", - "remove": "Remove Device" + "remove": "Remove Device", + "zigbee_information": "Zigbee Information" }, "confirmations": { "remove": "Are you sure that you want to remove the device?" }, + "device_signature": "Zigbee device signature", "last_seen": "Last Seen", "manuf": "by {manufacturer}", "no_area": "No Area", @@ -771,7 +773,8 @@ "services": { "reconfigure": "Reconfigure ZHA device (heal device). Use this if you are having issues with the device. If the device in question is a battery powered device please ensure it is awake and accepting commands when you use this service.", "remove": "Remove a device from the Zigbee network.", - "updateDeviceName": "Set a custom name for this device in the device registry." + "updateDeviceName": "Set a custom name for this device in the device registry.", + "zigbee_information": "View the Zigbee information for the device." }, "unknown": "Unknown", "zha_device_card": { diff --git a/translations/fr.json b/translations/fr.json index 403ab3d9f9..a2202fbf12 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -582,7 +582,7 @@ }, "related-items": { "area": "Zone", - "automation": "Partie des automatisations suivantes", + "automation": "Partie des automations suivantes", "device": "Appareil", "entity": "Entités liées", "group": "Partie des groupes suivants", @@ -958,8 +958,8 @@ }, "edit_ui": "Modifier avec l'interface utilisateur", "edit_yaml": "Modifier en tant que YAML", - "enable_disable": "Activer/Désactiver l'automatisation", - "introduction": "Utilisez les automatisations pour donner vie à votre maison", + "enable_disable": "Activer/Désactiver l'automation", + "introduction": "Utilisez les automations pour donner vie à votre maison", "load_error_not_editable": "Seules les automations dans automations.yaml sont modifiables.", "load_error_unknown": "Erreur lors du chargement de l'automation ( {err_no} ).", "save": "Sauvegarder", @@ -969,7 +969,7 @@ "delete_confirm": "Voulez-vous effacer ?", "duplicate": "Dupliquer", "header": "Déclencheurs", - "introduction": "Les déclencheurs sont ce qui lance le traitement d'une règle d'automatisation. Il est possible de spécifier plusieurs déclencheurs pour une même règle. Dès qu'un déclencheur est activé, Home Assistant validera les conditions, s'il y en a, et appellera l'action.\n\n[En apprendre plus sur les déclencheurs.](https://home-assistant.io/docs/automation/trigger/)", + "introduction": "Les déclencheurs sont ce qui lance le traitement d'une règle d'automation. Il est possible de spécifier plusieurs déclencheurs pour une même règle. Dès qu'un déclencheur est activé, Home Assistant validera les conditions, s'il y en a, et appellera l'action.\n\n[En apprendre plus sur les déclencheurs.](https://home-assistant.io/docs/automation/trigger/)", "learn_more": "En savoir plus sur les déclencheurs", "name": "Déclencheur", "type_select": "Type de déclencheur", @@ -1058,19 +1058,19 @@ }, "picker": { "add_automation": "Ajouter une automation", - "delete_automation": "Supprimer l'automatisation", - "delete_confirm": "Voulez-vous vraiment supprimer cette automatisation ?", - "edit_automation": "Modifier l'automatisation", + "delete_automation": "Supprimer l'automation", + "delete_confirm": "Voulez-vous vraiment supprimer cette automation ?", + "edit_automation": "Modifier l'automation", "header": "Éditeur d'automation", "headers": { "name": "Nom" }, "introduction": "L'éditeur d'automations vous permet de créer et modifier des automations. Veuillez lire les instructions ci-dessous pour vous assurer d'avoir configuré Home Assistant correctement.", - "learn_more": "En savoir plus sur les automatisations", + "learn_more": "En savoir plus sur les automations", "no_automations": "Il n'y a aucune automation modifiable.", - "only_editable": "Seules les automatisations définies dans automations.yaml sont modifiables.", + "only_editable": "Seules les automations définies dans automations.yaml sont modifiables.", "pick_automation": "Choisissez l'automation à modifier", - "show_info_automation": "Afficher des informations sur l'automatisation" + "show_info_automation": "Afficher des informations sur l'automation" } }, "cloud": { @@ -1133,7 +1133,7 @@ "loading": "Chargement ...", "manage": "Gérer", "no_hooks_yet": "Il semble que vous n'ayez pas encore de Webhooks. Commencez en configurer un ", - "no_hooks_yet_link_automation": "automatisation webhook", + "no_hooks_yet_link_automation": "automation webhook", "no_hooks_yet_link_integration": "intégration basée sur un Webhook", "no_hooks_yet2": "ou en créant un", "title": "Webhooks" @@ -1309,13 +1309,13 @@ "actions": { "caption": "Quand quelque chose est déclenché ..." }, - "automations": "Automatisations", + "automations": "Automations", "conditions": { "caption": "Ne faire quelque chose que si ..." }, - "create": "Créer une automatisation avec l'appareil", - "no_automations": "Aucune automatisation", - "no_device_automations": "Aucune automatisation n'est disponible pour cet appareil.", + "create": "Créer une automation avec l'appareil", + "no_automations": "Aucune automation", + "no_device_automations": "Aucune automation n'est disponible pour cet appareil.", "triggers": { "caption": "Faire quelque chose quand ..." } @@ -1428,8 +1428,8 @@ }, "header": "Configurer Home Assistant", "helpers": { - "caption": "Aides", - "description": "Éléments pouvant aider à construire des automatisations.", + "caption": "Entrées", + "description": "Éléments pouvant aider à construire des automations.", "dialog": { "add_helper": "Ajouter une aide", "add_platform": "Ajouter {platform}", @@ -1445,7 +1445,7 @@ } }, "types": { - "input_boolean": "Permuter", + "input_boolean": "Interrupteur", "input_datetime": "Date et/ou heure", "input_number": "Nombre", "input_select": "Liste déroulante", @@ -1695,7 +1695,7 @@ "description": "Redémarrer et arrêter le serveur Home Assistant", "section": { "reloading": { - "automation": "Recharger les automatisations", + "automation": "Recharger les automations", "core": "Recharger l'emplacement et les personnalisations", "group": "Recharger les groupes", "heading": "Rechargement de la configuration", @@ -1890,7 +1890,7 @@ "name": "Nom", "new_zone": "Nouvelle zone", "passive": "Passif", - "passive_note": "Les zones passives sont cachées dans l'interface utilisateur et ne sont pas utilisées comme emplacement pour les appareils suivis. Elles sont utiles si vous voulez les utiliser pour des automatisations.", + "passive_note": "Les zones passives sont cachées dans l'interface utilisateur et ne sont pas utilisées comme emplacement pour les appareils suivis. Elles sont utiles si vous voulez les utiliser pour des automations.", "radius": "Rayon", "required_error_msg": "Ce champ est requis", "update": "Mettre à jour" @@ -1899,7 +1899,7 @@ "edit_home_zone_narrow": "Le rayon de la zone d'habitation ne peut pas encore être modifié depuis le frontend. L'emplacement peut être modifié par rapport à la configuration générale.", "go_to_core_config": "Configuration générale", "home_zone_core_config": "L'emplacement de votre zone d'habitation est modifiable à partir de la page de configuration générale. Le rayon de la zone d'habitation ne peut pas encore être modifié depuis le frontend. Voulez-vous passer à la configuration générale ?", - "introduction": "Les zones vous permettent de spécifier certaines régions sur la terre. Lorsqu'une personne se trouve dans une zone, l'état prend le nom de la zone. Les zones peuvent également être utilisées comme déclencheur ou condition dans les configurations d'automatisation.", + "introduction": "Les zones vous permettent de spécifier certaines régions sur la terre. Lorsqu'une personne se trouve dans une zone, l'état prend le nom de la zone. Les zones peuvent également être utilisées comme déclencheur ou condition dans les configurations d'automation.", "no_zones_created_yet": "Il semble que vous n'ayez pas encore créé de zones." }, "zwave": { diff --git a/translations/it.json b/translations/it.json index 5ccc70477e..becf5dde22 100644 --- a/translations/it.json +++ b/translations/it.json @@ -509,6 +509,7 @@ "attributes": { "air_pressure": "Pressione atmosferica", "humidity": "Umidità", + "precipitation": "Precipitazioni", "temperature": "Temperatura", "visibility": "Visibilità", "wind_speed": "Velocità del vento" @@ -531,7 +532,9 @@ "wnw": "ONO", "wsw": "OSO" }, - "forecast": "Previsioni" + "forecast": "Previsioni", + "high": "Alto", + "low": "Basso" } }, "common": { @@ -543,6 +546,7 @@ "save": "Salva", "successfully_deleted": "Cancellato con successo", "successfully_saved": "Salvataggio riuscito", + "undo": "Annulla", "yes": "Sì" }, "components": { @@ -812,6 +816,10 @@ "areas": { "caption": "Aree", "create_area": "CREA AREA", + "data_table": { + "area": "Area", + "devices": "Dispositivi" + }, "delete": { "confirmation_text": "Tutti i dispositivi in quest'area non saranno assegnati.", "confirmation_title": "Sei sicuro di voler cancellare quest'area?" @@ -1054,6 +1062,9 @@ "delete_confirm": "Sei sicuro di voler eliminare questa automazione?", "edit_automation": "Modifica automazione", "header": "Editor di Automazione", + "headers": { + "name": "Nome" + }, "introduction": "L'Editor di Automazione consente di creare e modificare Automazioni. Seguire il collegamento seguente per leggere le istruzioni e assicurarsi di aver configurato correttamente Home Assistant.", "learn_more": "Per saperne di più sulle Automazioni", "no_automations": "Nessuna Automazione modificabile trovata", @@ -1334,6 +1345,7 @@ }, "info": "Informazioni sul dispositivo", "name": "Nome", + "no_devices": "Nessun dispositivo", "scene": { "create": "Crea una Scena con il dispositivo", "no_scenes": "Nessuna Scena", @@ -1638,6 +1650,9 @@ "delete_scene": "Cancella scena", "edit_scene": "Modifica scena", "header": "Editor di scene", + "headers": { + "name": "Nome" + }, "introduction": "L'Editor di Scene ti consente di creare e modificare Scene. Seguire il collegamento seguente per leggere le istruzioni e assicurarsi di aver configurato correttamente Home Assistant.", "learn_more": "Ulteriori informazioni sulle scene", "no_scenes": "Impossibile trovare scene modificabili", @@ -1665,9 +1680,13 @@ "add_script": "Aggiungi script", "edit_script": "Modifica script", "header": "Editor script", + "headers": { + "name": "Nome" + }, "introduction": "L'Editor di Script consente di creare e modificare Script. Seguire il collegamento seguente per leggere le istruzioni e assicurarsi di aver configurato correttamente Home Assistant.", "learn_more": "Ulteriori informazioni sugli script", "no_scripts": "Non è stato possibile trovare alcuno script modificabile", + "show_info": "Mostra informazioni sullo script", "trigger_script": "Attiva script" } }, @@ -1716,6 +1735,7 @@ "editor": { "activate_user": "Attiva utente", "active": "Attivo", + "admin": "Amministratore", "caption": "Visualizza utente", "change_password": "Cambia password", "confirm_user_deletion": "Sei sicuro di voler eliminare {name} ?", @@ -1725,14 +1745,22 @@ "group": "Gruppo", "group_update_failed": "L'aggiornamento del gruppo non è riuscito:", "id": "ID", + "name": "Nome", "owner": "Proprietario", "rename_user": "Rinomina utente", "system_generated": "Generato dal sistema", + "system_generated_users_not_editable": "Impossibile aggiornare gli utenti generati dal sistema.", "system_generated_users_not_removable": "Impossibile rimuovere gli utenti generati dal sistema.", "unnamed_user": "Utente senza nome", + "update_user": "Aggiorna", "user_rename_failed": "Rinominazione dell'utente fallita:" }, "picker": { + "headers": { + "group": "Gruppo", + "name": "Nome", + "system": "Sistema" + }, "system_generated": "Generato dal sistema", "title": "Utenti" } @@ -2135,6 +2163,10 @@ "description": "La scheda Filtro Entità consente di definire un elenco di entità che si desidera monitorare solo in un determinato stato.", "name": "Filtro Entità" }, + "entity": { + "description": "La scheda Entità offre una rapida panoramica dello stato dell'entità.", + "name": "Entità" + }, "gauge": { "description": "La scheda Indicatore è una scheda di base che consente di visualizzare visivamente i dati del sensore.", "name": "Indicatore", @@ -2147,8 +2179,10 @@ }, "generic": { "aspect_ratio": "Proporzioni", + "attribute": "Attributo", "camera_image": "Entità Fotocamera", "camera_view": "Vista fotocamera", + "double_tap_action": "Azione doppio tocco", "entities": "Entità", "entity": "Entità", "hold_action": "Azione di attesa", @@ -2199,6 +2233,7 @@ "default_zoom": "Ingrandimento predefinito", "description": "La scheda Mappa che permette di visualizzare le entità su una mappa.", "geo_location_sources": "Fonti di geolocalizzazione", + "hours_to_show": "Ore da mostrare", "name": "Mappa", "source": "Fonte" }, @@ -2255,6 +2290,10 @@ "name": "Previsioni del tempo" } }, + "cardpicker": { + "custom_card": "Personalizzato", + "no_description": "Nessuna descrizione disponibile." + }, "edit_card": { "add": "Aggiungi scheda", "delete": "Elimina scheda", @@ -2319,6 +2358,7 @@ "save_config": { "cancel": "Rinuncia", "close": "Chiudi", + "empty_config": "Iniziare con un cruscotto vuoto", "header": "Prendi il controllo della tua interfaccia utente di Lovelace", "para": "Per impostazione predefinita, Home Assistant gestirà l'Interfaccia Utente, aggiornandola quando nuove entità o componenti dell'IU Lovelace diventano disponibili. Se prendi il controllo non effettueremo più automaticamente le modifiche per te.", "para_sure": "Sei sicuro di voler prendere il controllo della tua interfaccia utente?", @@ -2568,6 +2608,11 @@ "submit": "Invia" }, "current_user": "Sei attualmente connesso come {fullName}.", + "dashboard": { + "description": "Scegliere un cruscotto di default per questo dispositivo.", + "dropdown_label": "Cruscotto", + "header": "Cruscotto" + }, "force_narrow": { "description": "Questo nasconderà la barra laterale per impostazione predefinita, in modo simile all'esperienza mobile", "header": "Nascondi sempre la barra laterale" diff --git a/translations/nb.json b/translations/nb.json index df1895d320..c0b412c41f 100644 --- a/translations/nb.json +++ b/translations/nb.json @@ -546,6 +546,7 @@ "save": "Lagre", "successfully_deleted": "Slettet", "successfully_saved": "Vellykket lagring", + "undo": "Angre", "yes": "Ja" }, "components": { @@ -1734,6 +1735,7 @@ "editor": { "activate_user": "Aktiver bruker", "active": "Aktiv", + "admin": "Administrator", "caption": "Vis bruker", "change_password": "Endre passord", "confirm_user_deletion": "Er du sikker på at du vil slette {name} ?", @@ -1747,6 +1749,7 @@ "owner": "Eier", "rename_user": "Gi nytt navn til bruker", "system_generated": "System generert", + "system_generated_users_not_editable": "Kan ikke oppdatere systemgenererte brukere.", "system_generated_users_not_removable": "Kan ikke fjerne systemgenererte brukere.", "unnamed_user": "Bruker uten navn", "update_user": "Oppdater", @@ -2161,6 +2164,7 @@ "name": "Entitetsfilter" }, "entity": { + "description": "Enhetskortet gir deg en rask oversikt over enhetens tilstand.", "name": "Entitet" }, "gauge": { diff --git a/translations/pl.json b/translations/pl.json index 815e757460..af85e32e83 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -30,8 +30,8 @@ "history_graph": "Wykres historii", "homeassistant": "Home Assistant", "image_processing": "Przetwarzanie obrazu", - "input_boolean": "Pole logiczne", - "input_datetime": "Pole daty czasu", + "input_boolean": "Pole wartości logicznej", + "input_datetime": "Pole daty i czasu", "input_number": "Pole numeryczne", "input_select": "Pole wyboru", "input_text": "Pole tekstowe", @@ -665,11 +665,11 @@ "time": "Czas" }, "input_number": { - "box": "Pole wprowadzania danych", + "box": "pole", "max": "Maksymalna wartość", "min": "Minimalna wartość", "mode": "Tryb wyświetlania", - "slider": "Suwak", + "slider": "suwak", "step": "Wielkość kroku suwaka", "unit_of_measurement": "Jednostka miary" }, @@ -1447,9 +1447,9 @@ "types": { "input_boolean": "Przełącznik", "input_datetime": "Data i/lub godzina", - "input_number": "Pole numeryczne", - "input_select": "Rozwijane pole wyboru", - "input_text": "Pole tekstowe" + "input_number": "Numer", + "input_select": "Pole wyboru", + "input_text": "Tekst" } }, "integrations": { diff --git a/translations/ru.json b/translations/ru.json index 0309709c2c..2681a80ade 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -629,7 +629,7 @@ "enabled_description": "Отключенные объекты не будут доступны в Home Assistant.", "enabled_label": "Включить объект", "entity_id": "ID объекта", - "icon": "Переопределение иконки", + "icon": "Значок", "icon_error": "Параметр значка должен быть указан в формате \"префикс:имя-значка\" (например: mdi:home)", "name": "Название", "note": "(может работать не со всеми интеграциями)", From 5c941e0afb1bfcc1d2a0bee2e268669028a57e22 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 16 Apr 2020 12:55:21 +0200 Subject: [PATCH 11/36] Remove initial value explanation --- src/panels/config/helpers/forms/ha-input_boolean-form.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/panels/config/helpers/forms/ha-input_boolean-form.ts b/src/panels/config/helpers/forms/ha-input_boolean-form.ts index fc44075538..55872f7250 100644 --- a/src/panels/config/helpers/forms/ha-input_boolean-form.ts +++ b/src/panels/config/helpers/forms/ha-input_boolean-form.ts @@ -75,10 +75,6 @@ class HaInputBooleanForm extends LitElement { "ui.dialogs.helper_settings.generic.icon" )} > -
- ${this.hass!.localize( - "ui.dialogs.helper_settings.generic.initial_value_explain" - )}
`; } From 0ccc7881483011b02a7d9fb5618a4a7b2706cb2c Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Fri, 17 Apr 2020 00:32:42 +0000 Subject: [PATCH 12/36] [ci skip] Translation update --- translations/ca.json | 7 ++-- translations/da.json | 9 +++-- translations/it.json | 7 ++-- translations/ko.json | 9 +++-- translations/nb.json | 7 ++-- translations/pt.json | 73 ++++++++++++++++++++++++++++++++++++--- translations/ru.json | 7 ++-- translations/sl.json | 68 ++++++++++++++++++++++++++++++------ translations/zh-Hant.json | 7 ++-- 9 files changed, 163 insertions(+), 31 deletions(-) diff --git a/translations/ca.json b/translations/ca.json index 5d813e5109..9be9d2c43a 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -758,11 +758,13 @@ "buttons": { "add": "Afegir dispositius", "reconfigure": "Reconfigurar dispositiu", - "remove": "Eliminar dispositiu" + "remove": "Eliminar dispositiu", + "zigbee_information": "Informació Zigbee" }, "confirmations": { "remove": "Estàs segur que vols eliminar el dispositiu?" }, + "device_signature": "Signatura Zigbee del dispositiu", "last_seen": "Vist per últim cop", "manuf": "per {manufacturer}", "no_area": "Sense Àrea", @@ -771,7 +773,8 @@ "services": { "reconfigure": "Reconfigura el dispositiu ZHA (dispositiu curatiu). Utilitza-ho si tens problemes amb el dispositiu. Si el dispositiu en qüestió està alimentat per bateria, assegura't que estigui despert i accepti ordres quan utilitzis aquest servei.", "remove": "Elimina un dispositiu de la xarxa Zigbee.", - "updateDeviceName": "Estableix un nom personalitzat pel dispositiu al registre de dispositius." + "updateDeviceName": "Estableix un nom personalitzat pel dispositiu al registre de dispositius.", + "zigbee_information": "Consulta la informació Zigbee del dispositiu." }, "unknown": "Desconeguda", "zha_device_card": { diff --git a/translations/da.json b/translations/da.json index 50edf120b8..16d4100a8e 100644 --- a/translations/da.json +++ b/translations/da.json @@ -758,11 +758,13 @@ "buttons": { "add": "Tilføj enheder", "reconfigure": "Genkonfigurer enhed", - "remove": "Fjern enhed" + "remove": "Fjern enhed", + "zigbee_information": "Zigbee-oplysninger" }, "confirmations": { "remove": "Er du sikker på, at du vil fjerne enheden?" }, + "device_signature": "Zigbee-enhedssignatur", "last_seen": "Sidst set", "manuf": "af {manufacturer}", "no_area": "Intet område", @@ -771,7 +773,8 @@ "services": { "reconfigure": "Rekonfigurer ZHA-enhed (helbred enheden). Brug dette, hvis du har problemer med enheden. Hvis den pågældende enhed er en batteridrevet enhed, skal du sørge for at den er vågen og accepterer kommandoer, når du bruger denne tjeneste.", "remove": "Fjern en enhed fra Zigbee-netværket.", - "updateDeviceName": "Angiv et brugerdefineret navn til denne enhed i enhedsregistret" + "updateDeviceName": "Angiv et brugerdefineret navn til denne enhed i enhedsregistret", + "zigbee_information": "Vis Zigbee-oplysningerne for enheden." }, "unknown": "Ukendt", "zha_device_card": { @@ -2140,7 +2143,7 @@ "change_type": "Skift type", "condition_explanation": "Kortet vises, når ALLE nedenstående betingelser er opfyldt.", "conditions": "Betingelser", - "current_state": "aktuelt", + "current_state": "aktuelle", "description": "Betinget-kortet viser et andet kort baseret på entitetstilstande.", "name": "Betinget", "state_equal": "Tilstand er lig med", diff --git a/translations/it.json b/translations/it.json index becf5dde22..038aee4e9b 100644 --- a/translations/it.json +++ b/translations/it.json @@ -758,11 +758,13 @@ "buttons": { "add": "Aggiungi dispositivi", "reconfigure": "Riconfigura dispositivo", - "remove": "Rimuovi dispositivo" + "remove": "Rimuovi dispositivo", + "zigbee_information": "Informazioni Zigbee" }, "confirmations": { "remove": "Sei sicuro di voler rimuovere il dispositivo?" }, + "device_signature": "Firma del dispositivo Zigbee", "last_seen": "Ultima visualizzazione", "manuf": "da {manufacturer}", "no_area": "Nessuna area", @@ -771,7 +773,8 @@ "services": { "reconfigure": "Riconfigurare il dispositivo ZHA (dispositivo di cura). Utilizzare questa opzione se riscontri problemi con il dispositivo. Se il dispositivo in questione è un dispositivo alimentato a batteria, assicurarsi che sia attivo e che accetti i comandi quando si utilizza questo servizio.", "remove": "Rimuovi un dispositivo dalla rete Zigbee.", - "updateDeviceName": "Imposta un nome personalizzato per questo dispositivo nel registro dispositivi." + "updateDeviceName": "Imposta un nome personalizzato per questo dispositivo nel registro dispositivi.", + "zigbee_information": "Visualizzare le informazioni Zigbee per il dispositivo." }, "unknown": "Sconosciuto", "zha_device_card": { diff --git a/translations/ko.json b/translations/ko.json index eb906a39ce..7a394ebecc 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -758,11 +758,13 @@ "buttons": { "add": "기기 추가", "reconfigure": "기기 재설정", - "remove": "기기 제거" + "remove": "기기 제거", + "zigbee_information": "Zigbee 정보" }, "confirmations": { "remove": "이 기기를 제거하시겠습니까?" }, + "device_signature": "Zigbee 기기서명", "last_seen": "마지막 확인", "manuf": "{manufacturer} 제조", "no_area": "영역 없음", @@ -771,7 +773,8 @@ "services": { "reconfigure": "ZHA 기기를 다시 구성 합니다. (기기 복구). 기기에 문제가 있는 경우 사용해주세요. 기기가 배터리로 작동하는 경우, 이 서비스를 사용할 때 기기가 켜져있고 통신이 가능한 상태인지 확인해주세요.", "remove": "Zigbee 네트워크에서 기기를 제거해주세요.", - "updateDeviceName": "이 기기의 사용자 정의 이름을 기기 레지스트리에 설정합니다." + "updateDeviceName": "이 기기의 사용자 정의 이름을 기기 레지스트리에 설정합니다.", + "zigbee_information": "기기에 대한 Zigbee 정보 보기." }, "unknown": "알 수 없슴", "zha_device_card": { @@ -2358,7 +2361,7 @@ "save_config": { "cancel": "아닙니다", "close": "닫기", - "empty_config": "비어있는 대시보드로시작", + "empty_config": "비어있는 대시보드로 시작", "header": "Lovelace UI 직접 관리하기", "para": "기본적으로 Home Assistant 는 사용자 인터페이스를 유지 관리하고, 사용할 수 있는 새로운 구성요소 또는 Lovelace 구성요소가 있을 때 업데이트를 합니다. 사용자가 직접 관리하는 경우 Home Assistant 는 더 이상 자동으로 변경하지 않습니다.", "para_sure": "사용자 인터페이스를 직접 관리하시겠습니까?", diff --git a/translations/nb.json b/translations/nb.json index c0b412c41f..ad6d1fc460 100644 --- a/translations/nb.json +++ b/translations/nb.json @@ -758,11 +758,13 @@ "buttons": { "add": "Legg til enheter", "reconfigure": "Rekonfigurer enhet", - "remove": "Fjern enhet" + "remove": "Fjern enhet", + "zigbee_information": "Zigbee informasjon" }, "confirmations": { "remove": "Er du sikker på at du vil fjerne enheten?" }, + "device_signature": "Zigbee-enhetssignatur", "last_seen": "Sist sett", "manuf": "av {manufacturer}", "no_area": "Intet område", @@ -771,7 +773,8 @@ "services": { "reconfigure": "Rekonfigurer ZHA-enhet (heal enhet). Bruk dette hvis du har problemer med enheten. Hvis den aktuelle enheten er en batteridrevet enhet, sørg for at den er våken og aksepterer kommandoer når du bruker denne tjenesten.", "remove": "Fjern en enhet fra Zigbee-nettverket.", - "updateDeviceName": "Angi et egendefinert navn for denne enheten i enhetsregisteret." + "updateDeviceName": "Angi et egendefinert navn for denne enheten i enhetsregisteret.", + "zigbee_information": "Vis Zigbee-informasjonen for enheten." }, "unknown": "Ukjent", "zha_device_card": { diff --git a/translations/pt.json b/translations/pt.json index 2199e30abf..ce72406a59 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -506,6 +506,7 @@ "attributes": { "air_pressure": "Press. Atmosférica", "humidity": "Humidade", + "precipitation": "Precipitação", "temperature": "Temperatura", "visibility": "Visibilidade", "wind_speed": "Vel. do vento" @@ -537,6 +538,7 @@ "no": "Não", "save": "Guardar", "successfully_saved": "Salva com sucesso", + "undo": "Desfazer", "yes": "Sim" }, "components": { @@ -589,6 +591,12 @@ "default_confirmation_title": "Tem a certeza?", "ok": "OK" }, + "helper_settings": { + "input_datetime": { + "date": "Data", + "time": "Hora" + } + }, "more_info_control": { "script": { "last_action": "Última ocorrência" @@ -631,8 +639,10 @@ "buttons": { "add": "Adicionar Dispositivos", "reconfigure": "Reconfigurar Dispositivo", - "remove": "Remover Dispositivo" + "remove": "Remover Dispositivo", + "zigbee_information": "Informação Zigbee" }, + "device_signature": "Assinatura do dispositivo Zigbee", "last_seen": "Visto pela última vez", "manuf": "por {manufacturer}", "no_area": "Nenhuma Área", @@ -641,7 +651,8 @@ "services": { "reconfigure": "Reconfigure o dispositivo ZHA (curar dispositivo). Utilize isto se estiver a ter problemas com o dispositivo. Se o dispositivo em questão for um dispositivo alimentado por uma bateria, ao utilizar este serviço certifique-se de que o equipamento está ativo e a aceitar comandos.", "remove": "Remover um dispositivo da rede Zigbee.", - "updateDeviceName": "Definir um nome personalizado para este dispositivo no registo do dispositivo." + "updateDeviceName": "Definir um nome personalizado para este dispositivo no registo do dispositivo.", + "zigbee_information": "Veja as informações do Zigbee para o dispositivo." }, "unknown": "Desconhecido", "zha_device_card": { @@ -685,6 +696,10 @@ "areas": { "caption": "Áreas", "create_area": "CRIAR ÁREA", + "delete": { + "confirmation_text": "Todos os dispositivos nesta área ficarão por atribuir.", + "confirmation_title": "Tem certeza de que deseja apagar esta área?" + }, "description": "Visão geral de todas as áreas da sua casa.", "editor": { "create": "CRIAR", @@ -920,6 +935,9 @@ "delete_confirm": "Tem a certeza que quer apagar esta automação?", "edit_automation": "Editar automação", "header": "Editor de automação", + "headers": { + "name": "Nome" + }, "introduction": "O editor de automação permite criar e editar automações. Leia [as instruções] (https://home-assistant.io/docs/automation/editor/) para se certificar de que configurou o Home Assistant corretamente.", "learn_more": "Saber mais sobre automações", "no_automations": "Não foi possível encontrar nenhuma automação editável", @@ -1131,12 +1149,14 @@ "device": "Dispositivo", "integration": "Integração", "manufacturer": "Fabricante", - "model": "Modelo" + "model": "Modelo", + "no_devices": "Sem dispositivos" }, "description": "Gerir dispositivos ligados", "details": "Aqui estão todos os detalhes do seu dispositivo.", "device_not_found": "Dispositivo não encontrado.", "info": "Informação do dispositivo", + "no_devices": "Sem dispositivos", "unknown_error": "Erro desconhecido", "unnamed_device": "Dispositivo sem nome" }, @@ -1201,6 +1221,7 @@ }, "failed_create_area": "Falha ao criar a área.", "finish": "Terminar", + "loading_first_time": "Por favor, aguarde enquanto a integração está a ser instalada", "name_new_area": "Nome da nova área?", "not_all_required_fields": "Nem todos os campos obrigatórios estão preenchidos.", "submit": "Enviar" @@ -1217,6 +1238,11 @@ "note_about_website_reference": "Existem mais disponíveis no" }, "introduction": "Aqui é possível configurar os seus componentes e o Home Assistant. Nem tudo é possível de ser configurado a partir da Interface Gráfica, mas estamos a trabalhar para isso.", + "lovelace": { + "dashboards": { + "default_dashboard": "Este é o painel de instrumentos padrão" + } + }, "person": { "add_person": "Adicionar Pessoa", "caption": "Pessoas", @@ -1263,6 +1289,9 @@ "picker": { "add_scene": "Adicionar cena", "edit_scene": "Editar cena", + "headers": { + "name": "Nome" + }, "no_scenes": "Não conseguimos encontrar nenhuma cena editável", "only_editable": "Apenas as cenas definidas em scenes.yaml são editáveis.", "pick_scene": "Escolha uma cena para editar", @@ -1279,7 +1308,11 @@ }, "picker": { "edit_script": "Editar script", - "header": "Editor de Script" + "header": "Editor de Script", + "headers": { + "name": "Nome" + }, + "show_info": "Mostrar informações sobre o script" } }, "server_control": { @@ -1325,6 +1358,7 @@ "editor": { "activate_user": "Ativar utilizador", "active": "Ativo", + "admin": "Administrador", "caption": "Ver utilizador", "change_password": "Alterar palavra-passe", "confirm_user_deletion": "Tem certeza de que deseja apagar {name} ?", @@ -1334,14 +1368,22 @@ "group": "Grupo", "group_update_failed": "Falha na atualização do grupo:", "id": "ID", + "name": "Nome", "owner": "Proprietário", "rename_user": "Alterar nome do utilizador", "system_generated": "Gerado pelo sistema", + "system_generated_users_not_editable": "Não foi possível atualizar os utilizadores gerados pelo sistema.", "system_generated_users_not_removable": "Não é possível remover usuários gerados pelo sistema.", "unnamed_user": "Utilizador sem nome", + "update_user": "Atualizar", "user_rename_failed": "Falha na renomeação do utilizador:" }, "picker": { + "headers": { + "group": "Grupo", + "name": "Nome", + "system": "Sistema" + }, "system_generated": "Gerado pelo sistema", "title": "Utilizadores" } @@ -1580,6 +1622,10 @@ "entity-filter": { "name": "Filtro de entidade" }, + "entity": { + "description": "O cartão de entidade fornece uma visão geral rápida do estado da sua entidade.", + "name": "Entidade" + }, "gauge": { "name": "Manómetro", "severity": { @@ -1590,8 +1636,10 @@ } }, "generic": { + "attribute": "Atributo", "camera_image": "Entidade de Câmera", "camera_view": "Vista da Câmera", + "double_tap_action": "Ação de toque duplo", "entities": "Entidades", "entity": "Entidade", "hours_to_show": "Horas a mostrar", @@ -1630,6 +1678,7 @@ "dark_mode": "Modo escuro?", "default_zoom": "Zoom padrão", "geo_location_sources": "Fontes de Geolocalização", + "hours_to_show": "Horas a mostrar", "name": "Mapa", "source": "Fonte" }, @@ -1667,6 +1716,9 @@ "name": "Previsão do tempo" } }, + "cardpicker": { + "no_description": "Não há descrição disponível." + }, "edit_card": { "add": "Adicionar Cartão", "delete": "Apagar Cartão", @@ -1690,7 +1742,10 @@ "edit": "Editar vista", "header": "Ver configuração", "move_left": "Mover vista para a esquerda", - "move_right": "Mover vista para a direita" + "move_right": "Mover vista para a direita", + "visibility": { + "select_users": "Selecione quais os utilizadores que devem ver esta visualização na navegação" + } }, "header": "Editar UI", "menu": { @@ -1715,6 +1770,7 @@ }, "save_config": { "cancel": "Cancelar", + "empty_config": "Começar com um painel de instrumentos vazio", "header": "Assumir controle sobre a interface do Lovelace", "para": "Por omissão o Home Assistant irá manter a sua interface de utilizador, atualizando-a sempre que uma nova entidade ou novos componentes Lovelace fiquem disponíveis. Se assumir o controlo, não faremos mais alterações automáticas por si.", "para_sure": "Tem certeza que deseja assumir o controlo sobre a interface de utilizador?", @@ -1726,6 +1782,7 @@ "configure_ui": "Configurar UI", "help": "Ajuda", "refresh": "Atualizar", + "reload_resources": "Recarregar recursos", "unused_entities": "Entidades não utilizadas" }, "reload_lovelace": "Recarregar Lovelace", @@ -1739,6 +1796,7 @@ "title": "Entidades não expostas" }, "warning": { + "attribute_not_found": "Atributo {attribute} não disponível em: {entity}", "entity_non_numeric": "A entidade é não numérica: {entity}", "entity_not_found": "Entidade não disponível: {entity}" } @@ -1932,6 +1990,11 @@ "submit": "Enviar" }, "current_user": "Esta atualmente ligado como {fullName}", + "dashboard": { + "description": "Escolha um painel de instrumentos padrão para este dispositivo.", + "dropdown_label": "Painel de instrumentos", + "header": "Painel de instrumentos" + }, "force_narrow": { "description": "Isto esconderá por defeito a barra lateral, semelhante à experiência no telemóvel.", "header": "Esconder sempre a barra lateral." diff --git a/translations/ru.json b/translations/ru.json index 2681a80ade..4c9bc4c9b6 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -755,11 +755,13 @@ "buttons": { "add": "Добавить устройства", "reconfigure": "Перенастроить устройство", - "remove": "Удалить устройство" + "remove": "Удалить устройство", + "zigbee_information": "Информация о Zigbee" }, "confirmations": { "remove": "Вы уверены, что хотите удалить это устройство?" }, + "device_signature": "Подпись устройства Zigbee", "last_seen": "Устройство было в сети", "manuf": "{manufacturer}", "no_area": "Не указано", @@ -768,7 +770,8 @@ "services": { "reconfigure": "Перенастройка устройства ZHA. Используйте эту службу, если у Вас есть проблемы с устройством. Если рассматриваемое устройство работает от батареи, пожалуйста, убедитесь, что оно не находится в режиме сна и принимает команды, когда вы запускаете эту службу.", "remove": "Удалить устройство из сети Zigbee.", - "updateDeviceName": "Укажите название для этого устройства в реестре устройств." + "updateDeviceName": "Укажите название для этого устройства в реестре устройств.", + "zigbee_information": "Просмотр информации о Zigbee устройстве." }, "unknown": "Неизвестно", "zha_device_card": { diff --git a/translations/sl.json b/translations/sl.json index 4c37ee4803..829233faa8 100644 --- a/translations/sl.json +++ b/translations/sl.json @@ -509,6 +509,7 @@ "attributes": { "air_pressure": "Zračni tlak", "humidity": "Vlažnost", + "precipitation": "Padavine", "temperature": "Temperatura", "visibility": "Vidljivost", "wind_speed": "Hitrost vetra" @@ -531,7 +532,9 @@ "wnw": "Zahod-severozahod", "wsw": "Zahod-jugozahod" }, - "forecast": "Napoved" + "forecast": "Napoved", + "high": "Visoko", + "low": "Nizko" } }, "common": { @@ -543,6 +546,7 @@ "save": "Shrani", "successfully_deleted": "Uspešno odstranjeno", "successfully_saved": "Shranjeno", + "undo": "Razveljavi", "yes": "Da" }, "components": { @@ -623,7 +627,7 @@ "dismiss": "Opusti", "editor": { "confirm_delete": "Ali ste prepričani, da želite izbrisati ta vnos?", - "delete": "BRISANJE", + "delete": "Izbriši", "enabled_cause": "Onemogočeno zaradi {cause}.", "enabled_description": "Onemogočeni subjekti ne bodo dodani v Home Assistant-a.", "enabled_label": "Omogoči entiteto", @@ -633,7 +637,7 @@ "name": "Preglasitev imena", "note": "Opomba: to morda še ne deluje z vsemi integracijami.", "unavailable": "Ta entiteta trenutno ni na voljo.", - "update": "POSODOBITEV" + "update": "Posodobi" }, "no_unique_id": "Ta entiteta nima edinstvenega ID-ja, zato njenih nastavitev ni mogoče upravljati iz uporabniškega vmesnika.", "related": "Povezano", @@ -666,7 +670,7 @@ "min": "Najmanjša vrednost", "mode": "Način prikaza", "slider": "Drsnik", - "step": "Velikost koraka drsnika", + "step": "Velikost koraka", "unit_of_measurement": "Merska enota" }, "input_select": { @@ -754,11 +758,13 @@ "buttons": { "add": "Dodajte naprave", "reconfigure": "Ponovno konfigurirajte napravo", - "remove": "Odstranite napravo" + "remove": "Odstranite napravo", + "zigbee_information": "Zigbee Informacije" }, "confirmations": { "remove": "Ali ste prepričani, da želite odstraniti napravo?" }, + "device_signature": "Podpis naprave Zigbee", "last_seen": "Nazadnje viden", "manuf": "naredil: {manufacturer}", "no_area": "Brez območja", @@ -767,7 +773,8 @@ "services": { "reconfigure": "Ponovno konfigurirajte napravo ZHA (\"pozdravite\" napravo). To uporabite, če imate z njo težave. Če ta naprava deluje na baterije, se prepričajte, da je budna in sprejema ukaze pri uporabi te storitve.", "remove": "Odstranite napravo iz omrežja Zigbee.", - "updateDeviceName": "Nastavite ime po meri za to napravo v registru naprav." + "updateDeviceName": "Nastavite ime po meri za to napravo v registru naprav.", + "zigbee_information": "Oglejte si informacije Zigbee za to napravo." }, "unknown": "Neznano", "zha_device_card": { @@ -812,20 +819,24 @@ "areas": { "caption": "Območja", "create_area": "USTVARITE OBMOČJE", + "data_table": { + "area": "Območje", + "devices": "Naprave" + }, "delete": { "confirmation_text": "Vse naprave na tem območju ne bodo dodeljene.", "confirmation_title": "Ali ste prepričani, da želite izbrisati to območje?" }, "description": "Pregled vseh območij v vašem domu.", "editor": { - "create": "USTVARITE", + "create": "Ustvari", "default_name": "Novo območje", - "delete": "BRISANJE", - "update": "POSODOBITEV" + "delete": "Izbriši", + "update": "Posodobi" }, "no_areas": "Izgleda, da še nimate območij!", "picker": { - "create_area": "USTVARITE OBMOČJE", + "create_area": "Ustvari območje", "header": "Območja", "integrations_page": "Stran za integracije", "introduction": "Področja se uporabljajo za organizacijo področja naprav. Te informacije bodo uporabljene v celotnem Home Assistant-u in vam bodo pomagale pri organizaciji vašega vmesnika, dovoljenj in integracij z drugimi sistemi.", @@ -1054,6 +1065,9 @@ "delete_confirm": "Ali ste prepričani, da želite izbrisati to avtomatizacijo?", "edit_automation": "Urejanje avtomatizacije", "header": "Urejevalnik avtomatizacije", + "headers": { + "name": "Ime" + }, "introduction": "Urejevalnik za avtomatizacijo vam omogoča ustvarjanje in urejanje avtomatizacij. Prosimo, da preberete [navodila] (https://home-assistant.io/docs/automation/editor/), da preverite, ali ste pravilno nastavili Home Assistant-a.", "learn_more": "Več o avtomatizacijah", "no_automations": "Ne moremo najti nobene avtomatizacije za urejanje", @@ -1334,6 +1348,7 @@ }, "info": "Informacije o napravi", "name": "Ime", + "no_devices": "Brez naprav", "scene": { "create": "Ustvarjanje scen z napravo", "no_scenes": "Ni scen", @@ -1638,6 +1653,9 @@ "delete_scene": "Brisanje scene", "edit_scene": "Urejanje scene", "header": "Urejevalnik scen", + "headers": { + "name": "Ime" + }, "introduction": "Urejevalnik scen vam omogoča njihovo ustvarjanje in urejanje. Upoštevajte spodnjo povezavo in si preberite navodila, da se prepričate, da ste pravilno konfigurirali Home Assistant.", "learn_more": "Preberite več o scenah", "no_scenes": "Nismo našli nobene scene za urejanje", @@ -1665,9 +1683,13 @@ "add_script": "Dodaj skripto", "edit_script": "Uredi skripto", "header": "Urejevalnik skript", + "headers": { + "name": "Ime" + }, "introduction": "Urejevalnik skript vam omogoča njihovo ustvarjanje in urejanje. Upoštevajte spodnjo povezavo in si preberite navodila, da se prepričate, da ste pravilno konfigurirali Home Assistant-a.", "learn_more": "Preberite več o skriptah", "no_scripts": "Nismo našli nobene skripte za urejanje", + "show_info": "Pokaži informacije o skripti", "trigger_script": "Sproži skripto" } }, @@ -1716,6 +1738,7 @@ "editor": { "activate_user": "Aktiviraj uporabnika", "active": "aktiven", + "admin": "Skrbnik", "caption": "Prikaži uporabnika", "change_password": "Spremeni geslo", "confirm_user_deletion": "Ali ste prepričani, da želite izbrisati {name}?", @@ -1725,14 +1748,22 @@ "group": "Skupina", "group_update_failed": "Posodobitev skupine ni uspela:", "id": "ID", + "name": "Ime", "owner": "Lastnik", "rename_user": "Preimenuj uporabnika", "system_generated": "Sistemsko generirano", + "system_generated_users_not_editable": "Sistemskih uporabnikov ni mogoče posodobiti.", "system_generated_users_not_removable": "Sistemskih uporabnikov ni mogoče odstraniti.", "unnamed_user": "Neimenovani uporabnik", + "update_user": "Posodobi", "user_rename_failed": "Preimenovanje uporabnika ni uspelo:" }, "picker": { + "headers": { + "group": "Skupina", + "name": "Ime", + "system": "Sistem" + }, "system_generated": "Sistemsko generirano", "title": "Uporabniki" } @@ -2135,6 +2166,10 @@ "description": "Kartica filter entitet vam omogoča, da določite seznam entitet, ki jih želite slediti samo, če so v določenem stanju.", "name": "Filter entitet" }, + "entity": { + "description": "Entity kartica vam omogoča hiter pregled stanja vašega subjekta.", + "name": "Subjekt" + }, "gauge": { "description": "Gauge kartica je osnovna kartica, ki omogoča vizualno videnje podatkov senzorjev.", "name": "Merilnik", @@ -2147,8 +2182,10 @@ }, "generic": { "aspect_ratio": "Razmerje Med Širino In Višino", + "attribute": "Atribut", "camera_image": "Subjekt kamere", "camera_view": "Pogled kamere", + "double_tap_action": "Dejanje dvojnega dotika", "entities": "Subjekti", "entity": "Subjekt", "hold_action": "dejanje pridržanja", @@ -2199,6 +2236,7 @@ "default_zoom": "Privzeta povečava", "description": "Kartica Map omogoča prikazovanje entitet na zemljevidu.", "geo_location_sources": "Geolokacijski viri", + "hours_to_show": "število ur za prikaz", "name": "Zemljevid", "source": "Vir" }, @@ -2255,6 +2293,10 @@ "name": "Vremenska napoved" } }, + "cardpicker": { + "custom_card": "Po meri", + "no_description": "Opis ni na voljo." + }, "edit_card": { "add": "Dodaj kartico", "delete": "Izbriši kartico", @@ -2319,6 +2361,7 @@ "save_config": { "cancel": "Pozabi", "close": "Zapri", + "empty_config": "Začnite s prazno nadzorno ploščo", "header": "Prevzemite nadzor nad lovelace vmesnikom", "para": "Home Assistant bo privzeto vzdrževal vaš uporabniški vmesnik in ga posodabljal, ko bodo na voljo novi subjekti ali komponente Lovelace UI. Če prevzamete nadzor, ne bomo več samodejno spreminjali sprememb za vas.", "para_sure": "Ali ste prepričani, da želite prevzeti nadzor nad vašim vmesnikom?", @@ -2568,6 +2611,11 @@ "submit": "Pošlji" }, "current_user": "Trenutno ste prijavljeni kot {fullName}.", + "dashboard": { + "description": "Izberite privzeto nadzorno ploščo za to napravo.", + "dropdown_label": "Nadzorna plošča", + "header": "Nadzorna plošča" + }, "force_narrow": { "description": "To bo privzeto skrilo stransko vrstico, podobno kot pri mobilnih napravah.", "header": "Vedno skrij stransko vrstico" diff --git a/translations/zh-Hant.json b/translations/zh-Hant.json index 256fa7303e..9e76abd75f 100644 --- a/translations/zh-Hant.json +++ b/translations/zh-Hant.json @@ -758,11 +758,13 @@ "buttons": { "add": "新增設備", "reconfigure": "重新設定設備", - "remove": "移除設備" + "remove": "移除設備", + "zigbee_information": "Zigbee 資訊" }, "confirmations": { "remove": "確定要移除此設備?" }, + "device_signature": "Zigbee 設備簽章", "last_seen": "上次出現", "manuf": "由 {manufacturer}", "no_area": "無分區", @@ -771,7 +773,8 @@ "services": { "reconfigure": "重新設定 ZHA Zibgee 設備(健康設備)。假如遇到設備問題,請使用此選項。假如有問題的設備為使用電池的設備,請先確定設備已喚醒並處於接受命令狀態。", "remove": "從 Zigbee 網路移除設備。", - "updateDeviceName": "於物件 ID 中自訂此設備名稱。" + "updateDeviceName": "於物件 ID 中自訂此設備名稱。", + "zigbee_information": "檢視設備 Zigbee 資訊。" }, "unknown": "未知", "zha_device_card": { From b516f10a352dca36048bffe85f9087265c30dcde Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2020 11:45:30 +0200 Subject: [PATCH 13/36] Bump https-proxy-agent from 2.2.1 to 2.2.4 (#5559) Bumps [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) from 2.2.1 to 2.2.4. - [Release notes](https://github.com/TooTallNate/node-https-proxy-agent/releases) - [Commits](https://github.com/TooTallNate/node-https-proxy-agent/compare/2.2.1...2.2.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7e44385bea..7600033c60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3357,10 +3357,10 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -agent-base@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" - integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== +agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== dependencies: es6-promisify "^5.0.0" @@ -6447,7 +6447,12 @@ es6-object-assign@^1.1.0: resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= -es6-promise@^4.0.3, es6-promise@^4.0.5: +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promise@^4.0.5: version "4.2.6" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f" integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q== @@ -8332,11 +8337,11 @@ https-browserify@^1.0.0: integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= https-proxy-agent@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" - integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== dependencies: - agent-base "^4.1.0" + agent-base "^4.3.0" debug "^3.1.0" husky@^1.3.1: @@ -10331,11 +10336,16 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.1, ms@^2.1.1: +ms@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + multer@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.1.tgz#24b12a416a22fec2ade810539184bf138720159e" From 97c454aa0d691a6a219dc0e1d3936d896bf3933d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 17 Apr 2020 09:01:45 -0700 Subject: [PATCH 14/36] Update domain translation string (#5558) --- src/data/integration.ts | 2 +- .../domain-toggler/dialog-domain-toggler.ts | 3 +- .../configurator-notification-item.ts | 5 ++- .../thingtalk/ha-thingtalk-placeholders.ts | 5 ++- .../developer-tools/info/integrations-card.ts | 3 +- .../info/system-health-card.ts | 5 ++- .../logs/dialog-system-log-detail.ts | 5 +-- .../common/generate-lovelace-config.ts | 3 +- src/panels/lovelace/ha-panel-lovelace.ts | 3 +- src/translations/en.json | 44 ------------------- 10 files changed, 20 insertions(+), 58 deletions(-) diff --git a/src/data/integration.ts b/src/data/integration.ts index 7607bd3dcb..9290775bcd 100644 --- a/src/data/integration.ts +++ b/src/data/integration.ts @@ -21,7 +21,7 @@ export const integrationIssuesUrl = (domain: string) => `https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+${domain}%22`; export const domainToName = (localize: LocalizeFunc, domain: string) => - localize(`domain.${domain}`) || domain; + localize(`component.${domain}.title`) || domain; export const fetchIntegrationManifests = (hass: HomeAssistant) => hass.callWS({ type: "manifest/list" }); diff --git a/src/dialogs/domain-toggler/dialog-domain-toggler.ts b/src/dialogs/domain-toggler/dialog-domain-toggler.ts index 3d27b4f089..14fac5294f 100644 --- a/src/dialogs/domain-toggler/dialog-domain-toggler.ts +++ b/src/dialogs/domain-toggler/dialog-domain-toggler.ts @@ -12,6 +12,7 @@ import { PolymerChangedEvent } from "../../polymer-types"; import { haStyleDialog } from "../../resources/styles"; import { HomeAssistant } from "../../types"; import { HaDomainTogglerDialogParams } from "./show-dialog-domain-toggler"; +import { domainToName } from "../../data/integration"; @customElement("dialog-domain-toggler") class DomainTogglerDialog extends LitElement { @@ -29,7 +30,7 @@ class DomainTogglerDialog extends LitElement { } const domains = this._params.domains - .map((domain) => [this.hass.localize(`domain.${domain}`), domain]) + .map((domain) => [domainToName(this.hass.localize, domain), domain]) .sort(); return html` diff --git a/src/dialogs/notifications/configurator-notification-item.ts b/src/dialogs/notifications/configurator-notification-item.ts index 0c556dfc68..178ebeff97 100644 --- a/src/dialogs/notifications/configurator-notification-item.ts +++ b/src/dialogs/notifications/configurator-notification-item.ts @@ -10,6 +10,7 @@ import { fireEvent } from "../../common/dom/fire_event"; import { PersitentNotificationEntity } from "../../data/persistent_notification"; import { HomeAssistant } from "../../types"; import "./notification-item-template"; +import { domainToName } from "../../data/integration"; @customElement("configurator-notification-item") export class HuiConfiguratorNotificationItem extends LitElement { @@ -24,7 +25,9 @@ export class HuiConfiguratorNotificationItem extends LitElement { return html` - ${this.hass.localize("domain.configurator")} + + ${domainToName(this.hass.localize, "configurator")} +
${this.hass.localize( diff --git a/src/panels/config/automation/thingtalk/ha-thingtalk-placeholders.ts b/src/panels/config/automation/thingtalk/ha-thingtalk-placeholders.ts index ea937d71a3..0e233445a8 100644 --- a/src/panels/config/automation/thingtalk/ha-thingtalk-placeholders.ts +++ b/src/panels/config/automation/thingtalk/ha-thingtalk-placeholders.ts @@ -27,6 +27,7 @@ import { PolymerChangedEvent } from "../../../../polymer-types"; import { haStyleDialog } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; import { Placeholder, PlaceholderContainer } from "./dialog-thingtalk"; +import { domainToName } from "../../../../data/integration"; declare global { // for fire event @@ -320,7 +321,7 @@ export class ThingTalkPlaceholders extends SubscribeMixin(LitElement) { private _getLabel(domains: string[], deviceClasses?: string[]) { return `${domains - .map((domain) => this.hass.localize(`domain.${domain}`)) + .map((domain) => domainToName(this.hass.localize, domain)) .join(", ")}${ deviceClasses ? ` of type ${deviceClasses.join(", ")}` : "" }`; @@ -410,7 +411,7 @@ export class ThingTalkPlaceholders extends SubscribeMixin(LitElement) { if (entities.length === 0) { // Should not happen because we filter the device picker on domain this._error = `No ${placeholder.domains - .map((domain) => this.hass.localize(`domain.${domain}`)) + .map((domain) => domainToName(this.hass.localize, domain)) .join(", ")} entities found in this device.`; } else if (entities.length === 1) { applyPatch( diff --git a/src/panels/developer-tools/info/integrations-card.ts b/src/panels/developer-tools/info/integrations-card.ts index 12b6e29f59..980b554012 100644 --- a/src/panels/developer-tools/info/integrations-card.ts +++ b/src/panels/developer-tools/info/integrations-card.ts @@ -12,6 +12,7 @@ import { integrationIssuesUrl, IntegrationManifest, fetchIntegrationManifests, + domainToName, } from "../../../data/integration"; import { HomeAssistant } from "../../../types"; @@ -48,7 +49,7 @@ class IntegrationsCard extends LitElement { /> - ${manifest?.name}
+ ${domainToName(this.hass.localize, domain)}
${domain} ${!manifest diff --git a/src/panels/developer-tools/info/system-health-card.ts b/src/panels/developer-tools/info/system-health-card.ts index d595b494bc..2fdec54f37 100644 --- a/src/panels/developer-tools/info/system-health-card.ts +++ b/src/panels/developer-tools/info/system-health-card.ts @@ -13,6 +13,7 @@ import { SystemHealthInfo, } from "../../../data/system_health"; import { HomeAssistant } from "../../../types"; +import { domainToName } from "../../../data/integration"; const sortKeys = (a: string, b: string) => { if (a === "homeassistant") { @@ -64,7 +65,7 @@ class SystemHealthCard extends LitElement { } if (domain !== "homeassistant") { sections.push( - html`

${this.hass.localize(`domain.${domain}`) || domain}

` + html`

${domainToName(this.hass.localize, domain)}

` ); } sections.push(html` @@ -76,7 +77,7 @@ class SystemHealthCard extends LitElement { } return html` - +
${sections}
`; diff --git a/src/panels/developer-tools/logs/dialog-system-log-detail.ts b/src/panels/developer-tools/logs/dialog-system-log-detail.ts index 255884558a..cfa468c93a 100644 --- a/src/panels/developer-tools/logs/dialog-system-log-detail.ts +++ b/src/panels/developer-tools/logs/dialog-system-log-detail.ts @@ -73,10 +73,7 @@ class DialogSystemLogDetail extends LitElement { ${integration ? html`
- Integration: - ${this._manifest - ? this._manifest.name - : domainToName(this.hass.localize, integration)} + Integration: ${domainToName(this.hass.localize, integration)} ${!this._manifest || // Can happen with custom integrations !this._manifest.documentation diff --git a/src/panels/lovelace/common/generate-lovelace-config.ts b/src/panels/lovelace/common/generate-lovelace-config.ts index a5aafbadeb..6190d6e4fb 100644 --- a/src/panels/lovelace/common/generate-lovelace-config.ts +++ b/src/panels/lovelace/common/generate-lovelace-config.ts @@ -41,6 +41,7 @@ import { } from "../cards/types"; import { processEditorEntities } from "../editor/process-editor-entities"; import { LovelaceRowConfig, WeblinkConfig } from "../entity-rows/types"; +import { domainToName } from "../../../data/integration"; const DEFAULT_VIEW_ENTITY_ID = "group.default_view"; const DOMAINS_BADGES = [ @@ -301,7 +302,7 @@ const generateViewConfig = ( entities[entityId], ]), { - title: localize(`domain.${domain}`), + title: domainToName(localize, domain), } ) ); diff --git a/src/panels/lovelace/ha-panel-lovelace.ts b/src/panels/lovelace/ha-panel-lovelace.ts index b0e1d7a4fc..e405ac902f 100644 --- a/src/panels/lovelace/ha-panel-lovelace.ts +++ b/src/panels/lovelace/ha-panel-lovelace.ts @@ -25,6 +25,7 @@ import { loadLovelaceResources } from "./common/load-resources"; import { showSaveDialog } from "./editor/show-save-config-dialog"; import "./hui-root"; import { Lovelace } from "./types"; +import { domainToName } from "../../data/integration"; (window as any).loadCardHelpers = () => import("./custom-card-helpers"); @@ -113,7 +114,7 @@ class LovelacePanel extends LitElement { if (state === "error") { return html` diff --git a/src/translations/en.json b/src/translations/en.json index 1d2cb0a058..cceeafa19a 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1,48 +1,4 @@ { - "domain": { - "alarm_control_panel": "Alarm control panel", - "automation": "Automation", - "binary_sensor": "Binary sensor", - "calendar": "Calendar", - "camera": "Camera", - "climate": "Climate", - "configurator": "Configurator", - "conversation": "Conversation", - "cover": "Cover", - "device_tracker": "Device tracker", - "fan": "Fan", - "group": "Group", - "hassio": "Hass.io", - "history_graph": "History graph", - "homeassistant": "Home Assistant", - "image_processing": "Image processing", - "input_boolean": "Input boolean", - "input_datetime": "Input datetime", - "input_number": "Input number", - "input_select": "Input select", - "input_text": "Input text", - "light": "Light", - "lock": "Lock", - "lovelace": "Lovelace", - "mailbox": "Mailbox", - "media_player": "Media player", - "notify": "Notify", - "person": "Person", - "plant": "Plant", - "proximity": "Proximity", - "remote": "Remote", - "scene": "Scene", - "script": "Script", - "sensor": "Sensor", - "sun": "Sun", - "switch": "Switch", - "system_health": "System Health", - "updater": "Updater", - "vacuum": "Vacuum", - "weblink": "Weblink", - "zha": "ZHA", - "zwave": "Z-Wave" - }, "panel": { "calendar": "Calendar", "config": "Configuration", From f57754212c219f79cc0671be7e2dabd53b755b9d Mon Sep 17 00:00:00 2001 From: Aidan Timson Date: Fri, 17 Apr 2020 22:29:49 +0100 Subject: [PATCH 15/36] Add Search to Card Picker (#5497) * Add Search to Card Picker * Force focus * Remove autofocus * Fix from rebase * Commit suggestion Co-Authored-By: Bram Kragten * Flip autofocus * Cache cards * Make cards a property * Add missing custom cards * Set cards to render elements * Commit suggestion Co-Authored-By: Bram Kragten * Update src/panels/lovelace/editor/card-editor/hui-card-picker.ts Co-Authored-By: Bram Kragten * Make card preview max width match columns * Typo * Add autofocus where wanted * Update src/common/search/search-input.ts Co-Authored-By: Bram Kragten * Update src/dialogs/config-flow/step-flow-pick-handler.ts Co-Authored-By: Bram Kragten Co-authored-by: Bram Kragten --- src/common/search/search-input.ts | 5 +- .../config-flow/step-flow-pick-handler.ts | 1 + .../editor/card-editor/hui-card-picker.ts | 170 ++++++++++++------ 3 files changed, 118 insertions(+), 58 deletions(-) diff --git a/src/common/search/search-input.ts b/src/common/search/search-input.ts index c04395a8f5..46f3745335 100644 --- a/src/common/search/search-input.ts +++ b/src/common/search/search-input.ts @@ -22,6 +22,9 @@ class SearchInput extends LitElement { @property({ type: Boolean, attribute: "no-underline" }) public noUnderline = false; + @property({ type: Boolean }) + public autofocus = false; + public focus() { this.shadowRoot!.querySelector("paper-input")!.focus(); } @@ -38,7 +41,7 @@ class SearchInput extends LitElement { ${this.hass.localize("ui.panel.config.integrations.new")} 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 0c8550f39a..eb0e767a18 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts @@ -10,12 +10,18 @@ import { } from "lit-element"; import { classMap } from "lit-html/directives/class-map"; import { until } from "lit-html/directives/until"; +import memoizeOne from "memoize-one"; +import * as Fuse from "fuse.js"; + +import { CardPickTarget } from "../types"; +import { LovelaceCard } from "../../types"; +import { LovelaceCardConfig, LovelaceConfig } from "../../../../data/lovelace"; import { fireEvent } from "../../../../common/dom/fire_event"; import { UNAVAILABLE_STATES } from "../../../../data/entity"; -import { LovelaceCardConfig, LovelaceConfig } from "../../../../data/lovelace"; import { - customCards, CUSTOM_TYPE_PREFIX, + CustomCardEntry, + customCards, getCustomCardEntry, } from "../../../../data/lovelace_custom_cards"; import { HomeAssistant } from "../../../../types"; @@ -24,9 +30,22 @@ import { computeUsedEntities, } from "../../common/compute-unused-entities"; import { createCardElement } from "../../create-element/create-card-element"; -import { LovelaceCard } from "../../types"; import { getCardStubConfig } from "../get-card-stub-config"; -import { CardPickTarget } from "../types"; + +import "../../../../common/search/search-input"; + +interface Card { + type: string; + name?: string; + description?: string; + noElement?: boolean; + isCustom?: boolean; +} + +interface CardElement { + card: Card; + element: TemplateResult; +} const previewCards: string[] = [ "alarm-panel", @@ -63,14 +82,40 @@ const nonPreviewCards: string[] = [ export class HuiCardPicker extends LitElement { @property() public hass?: HomeAssistant; + @property() private _cards: CardElement[] = []; + public lovelace?: LovelaceConfig; public cardPicked?: (cardConf: LovelaceCardConfig) => void; + private _filter?: string; + private _unusedEntities?: string[]; private _usedEntities?: string[]; + private _filterCards = memoizeOne( + (cardElements: CardElement[], filter?: string): CardElement[] => { + if (filter) { + let cards = cardElements.map( + (cardElement: CardElement) => cardElement.card + ); + const options: Fuse.FuseOptions = { + keys: ["type", "name", "description"], + caseSensitive: false, + minMatchCharLength: 2, + threshold: 0.2, + }; + const fuse = new Fuse(cards, options); + cards = fuse.search(filter); + cardElements = cardElements.filter((cardElement: CardElement) => + cards.includes(cardElement.card) + ); + } + return cardElements; + } + ); + protected render(): TemplateResult { if ( !this.hass || @@ -82,50 +127,16 @@ export class HuiCardPicker extends LitElement { } return html` +
- ${previewCards.map((type: string) => { - return html` - ${until( - this._renderCardElement(type), - html` -
- -
- ` - )} - `; - })} - ${nonPreviewCards.map((type: string) => { - return html` - ${until( - this._renderCardElement(type, true), - html` -
- -
- ` - )} - `; - })} + ${this._filterCards(this._cards, this._filter).map( + (cardElement: CardElement) => cardElement.element + )}
- ${customCards.length - ? html` -
- ${customCards.map((card) => { - return html` - ${until( - this._renderCardElement(card.type, true, true), - html` -
- -
- ` - )} - `; - })} -
- ` - : ""}
({ + type, + name: this.hass!.localize(`ui.panel.lovelace.editor.card.${type}.name`), + description: this.hass!.localize( + `ui.panel.lovelace.editor.card.${type}.description` + ), + })) + .concat( + nonPreviewCards.map((type: string) => ({ + type, + name: this.hass!.localize( + `ui.panel.lovelace.editor.card.${type}.name` + ), + description: this.hass!.localize( + `ui.panel.lovelace.editor.card.${type}.description` + ), + noElement: true, + })) + ); + if (customCards.length > 0) { + cards = cards.concat( + customCards.map((ccard: CustomCardEntry) => ({ + type: ccard.type, + name: ccard.name, + description: ccard.description, + noElement: true, + isCustom: true, + })) + ); + } + this._cards = cards.map((card: Card) => ({ + card: card, + element: html`${until( + this._renderCardElement(card), + html` +
+ +
+ ` + )}`, + })); + } + + private _handleSearchChange(ev: CustomEvent) { + this._filter = ev.detail.value; this.requestUpdate(); } @@ -194,6 +255,7 @@ export class HuiCardPicker extends LitElement { .card { height: 100%; + max-width: 500px; display: flex; flex-direction: column; border-radius: 4px; @@ -279,11 +341,9 @@ export class HuiCardPicker extends LitElement { return element; } - private async _renderCardElement( - type: string, - noElement = false, - isCustom = false - ): Promise { + private async _renderCardElement(card: Card): Promise { + let { type } = card; + const { noElement, isCustom, name, description } = card; const customCard = isCustom ? getCustomCardEntry(type) : undefined; if (isCustom) { type = `${CUSTOM_TYPE_PREFIX}${type}`; @@ -324,18 +384,14 @@ export class HuiCardPicker extends LitElement { this.hass!.localize( `ui.panel.lovelace.editor.cardpicker.no_description` ) - : this.hass!.localize( - `ui.panel.lovelace.editor.card.${cardConfig.type}.description` - )} + : description}
${customCard ? `${this.hass!.localize( "ui.panel.lovelace.editor.cardpicker.custom_card" )}: ${customCard.name || customCard.type}` - : this.hass!.localize( - `ui.panel.lovelace.editor.card.${cardConfig.type}.name` - )} + : name}
`; From f91b46e88ca0b1764687179ffe43b70a25d185f5 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Sat, 18 Apr 2020 00:32:56 +0000 Subject: [PATCH 16/36] [ci skip] Translation update --- translations/de.json | 7 ++- translations/es.json | 7 ++- translations/pt.json | 97 +++++++++++++++++++++++++++++++++++---- translations/ru.json | 4 +- translations/zh-Hans.json | 7 ++- 5 files changed, 104 insertions(+), 18 deletions(-) diff --git a/translations/de.json b/translations/de.json index dccf2b1405..a21fdeb3c4 100644 --- a/translations/de.json +++ b/translations/de.json @@ -758,11 +758,13 @@ "buttons": { "add": "Geräte hinzufügen", "reconfigure": "Gerät neu konfigurieren", - "remove": "Gerät entfernen" + "remove": "Gerät entfernen", + "zigbee_information": "ZigBee-Informationen" }, "confirmations": { "remove": "Möchtest du das Gerät wirklich entfernen?" }, + "device_signature": "ZigBee-Gerätesignatur", "last_seen": "Zuletzt gesehen", "manuf": "von {manufacturer}", "no_area": "Kein Bereich", @@ -771,7 +773,8 @@ "services": { "reconfigure": "Konfigurieren Sie das ZHA-Gerät neu (Gerät heilen). Verwenden Sie diese Option, wenn Sie Probleme mit dem Gerät haben. Wenn es sich bei dem fraglichen Gerät um ein batteriebetriebenes Gerät handelt, vergewissern Sie sich, dass es wach ist und Befehle akzeptiert, wenn Sie diesen Dienst nutzen.", "remove": "Ein Gerät aus dem ZigBee-Netzwerk entfernen.", - "updateDeviceName": "Lege einen benutzerdefinierten Namen für dieses Gerät in der Geräteregistrierung fest." + "updateDeviceName": "Lege einen benutzerdefinierten Namen für dieses Gerät in der Geräteregistrierung fest.", + "zigbee_information": "Zeigen Sie die ZigBee-Informationen für das Gerät an." }, "unknown": "Unbekannt", "zha_device_card": { diff --git a/translations/es.json b/translations/es.json index aaf330d3df..41d4aedbdf 100644 --- a/translations/es.json +++ b/translations/es.json @@ -758,11 +758,13 @@ "buttons": { "add": "Añadir dispositivos", "reconfigure": "Reconfigurar dispositivo", - "remove": "Eliminar dispositivos" + "remove": "Eliminar dispositivos", + "zigbee_information": "Información Zigbee" }, "confirmations": { "remove": "¿Estás seguro de que quieres eliminar este dispositivo?" }, + "device_signature": "Firma del dispositivo Zigbee", "last_seen": "Ultima vez visto", "manuf": "por {manufacturer}", "no_area": "Ningún área", @@ -771,7 +773,8 @@ "services": { "reconfigure": "Reconfigura el dispositivo ZHA (curar dispositivo). Usa esto si tienes problemas con el dispositivo. Si el dispositivo en cuestión es un dispositivo alimentado por batería, asegúrate de que está activo y aceptando comandos cuando uses este servicio.", "remove": "Eliminar un dispositivo de la red Zigbee.", - "updateDeviceName": "Establece un nombre personalizado para este dispositivo en el registro de dispositivos." + "updateDeviceName": "Establece un nombre personalizado para este dispositivo en el registro de dispositivos.", + "zigbee_information": "Ver la información Zigbee para el dispositivo." }, "unknown": "Desconocido", "zha_device_card": { diff --git a/translations/pt.json b/translations/pt.json index ce72406a59..9d10555b28 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -394,7 +394,7 @@ }, "ui": { "auth_store": { - "ask": "Deseja guardar este login?", + "ask": "Deseja continuar com sessão iniciada?", "confirm": "Guardar login", "decline": "Não, obrigado" }, @@ -586,6 +586,9 @@ "ok": "", "title": "Tem a certeza?" }, + "domain_toggler": { + "title": "Alternar domínios" + }, "generic": { "cancel": "Cancelar", "default_confirmation_title": "Tem a certeza?", @@ -630,7 +633,9 @@ } }, "voice_command": { + "did_not_hear": "O Home Assistant não ouve nada", "error": "Oops, ocorreu um erro", + "found": "Encontrei o seguinte para si:", "how_can_i_help": "Como posso ajudar?", "label": "Escreva uma pergunta e pressione 'Enter'", "label_voice": "Digite e pressione 'Enter' ou toque no microfone para falar" @@ -949,8 +954,13 @@ "cloud": { "account": { "alexa": { + "config_documentation": "Documentação de configuração", "disable": "Desativar", "enable": "Ativar", + "enable_ha_skill": "Ativar a skill Home Assistant para a Alexa.", + "enable_state_reporting": "Ativar relatório de estado", + "info": "Com a integração Alexa para o Home Assistant Cloud, você poderá controlar todos os seus dispositivos Home Assistant através de qualquer dispositivo Alexa.", + "info_state_reporting": "Se você ativar o relatório de estado, o Home Assistant enviará todas as alterações de estado das entidades expostas à Amazon. Isso permite que você veja sempre os estados mais recentes na aplicação Alexa e use as alterações de estado para criar rotinas.", "manage_entities": "Gerir Entidades", "state_reporting_error": "Indisponível para {enable_disable} reportar estado.", "sync_entities": "Sincronizar Entidades", @@ -959,36 +969,55 @@ }, "connected": "Ligado", "connection_status": "Estado da ligação na cloud", + "fetching_subscription": "A buscar assinatura...", "google": { + "config_documentation": "Documentação de configuração", + "devices_pin": "Pin para os Dispositivos de Segurança", + "enable_ha_skill": "Ativar a skill Home Assistant para o Google Assistant", "enable_state_reporting": "Habilitar O Relatório De Estado", + "enter_pin_error": "Não é possível guardar o pin:", + "enter_pin_hint": "Insira um PIN para usar dispositivos de segurança", + "enter_pin_info": "Por favor, insira um pin para interagir com os dispositivos de segurança. Os dispositivos de segurança são portas, portões de garagem e fechaduras. Ser-lhe-á pedido para dizer/inserir este pin quando interagir com tais dispositivos através do Google Assistant.", "info": "Com a integração do Google Assistant para o Home Assistant Cloud, poderá controlar todos os seus dispositivos do Home Assistant por qualquer dispositivo com Google Assistant ativado.", + "info_state_reporting": "Se você ativar o relatório de estado, o Home Assistant enviará todas as alterações de estado das entidades expostas à Amazon. Isso permite que você veja sempre os estados mais recentes na aplicação Google Home.", "manage_entities": "Gerir Entidades", "security_devices": "Dispositivos de segurança", "sync_entities": "Sincronizar entidades com o Google", "title": "" }, "integrations": "Integrações", + "integrations_introduction": "As integrações para o Home Assistant Cloud permitem-lhe ligar-se aos serviços na nuvem sem ter de expor publicamente o seu Home Assistant na Internet.", + "integrations_introduction2": "Consulte o site para ", "integrations_link_all_features": " todas as funcionalidades disponíveis", "manage_account": "Gerir conta", "nabu_casa_account": "Conta Nabu Casa", "not_connected": "Não Ligado", "remote": { + "access_is_being_prepared": "O acesso remoto está a ser preparado. Iremos notificá-lo quando estiver pronto.", "certificate_info": "Informações do certificado", + "info": "O Home Assistant Cloud oferece uma ligação remota segura à sua instância enquanto estiver fora de casa.", "instance_is_available": "A sua instância está disponível em", "instance_will_be_available": "Sua instância estará disponível em", "link_learn_how_it_works": "Aprenda como funciona", "title": "Controle Remoto" }, "sign_out": "Terminar sessão", + "thank_you_note": "Obrigado por fazer parte do Home Assistant Cloud. É por causa de pessoas como você que somos capazes de fazer uma ótima experiência de automação residencial para todos. Muito obrigado!", "webhooks": { + "disable_hook_error_msg": "Falha ao desativar o webhook:", + "info": "Qualquer coisa que esteja configurada para ser acionada por um webhook pode receber um URL público para permitir que você envie dados de volta para o Home Assistant de qualquer lugar, sem expor a sua instância à Internet.", + "link_learn_more": "Saiba mais sobre como criar automações baseadas em webhook.", "loading": "A carregar...", "manage": "Gerir", + "no_hooks_yet": "Parece que você ainda não tem webhooks. Comece, configurando um", "no_hooks_yet_link_automation": "automação de webhook", + "no_hooks_yet_link_integration": "integração baseada em webhook", "no_hooks_yet2": " ou criando um ", "title": "" } }, "alexa": { + "banner": "Editar as entidades que são expostas através desta UI está desabilitada porque você configurou entity filters em configuration.yaml.", "expose": "Expor para Alexa", "exposed_entities": "Entidades expostas", "not_exposed_entities": "Entidades não expostas", @@ -1022,9 +1051,11 @@ "email_error_msg": "E-mail inválido", "instructions": "Introduza o seu endereço de e-mail e nós lhe enviaremos um link para redefinir sua password.", "send_reset_email": "Enviar e-mail de redefinição", + "subtitle": "Esquecer a senha", "title": "Esqueci-me da palavra-passe" }, "google": { + "banner": "Editar as entidades que são expostas através desta UI está desabilitada porque você configurou entity filters em configuration.yaml.", "disable_2FA": "Desativar a autenticação de dois fatores", "expose": "Expor ao Google Assistant", "exposed_entities": "Entidades expostas", @@ -1034,6 +1065,7 @@ }, "login": { "alert_email_confirm_necessary": "É necessário confirmar o seu e-mail antes de fazer login.", + "alert_password_change_required": "É necessário alterar a sua password antes de fazer login.", "dismiss": "Fechar", "email": "", "email_error_msg": "E-mail inválido", @@ -1046,9 +1078,12 @@ "password": "Palavra-passe", "password_error_msg": "As palavras-passe têm pelo menos 8 caracteres", "sign_in": "Entrar", - "title": "Cloud Login" + "start_trial": "Inicie a sua avaliação gratuita de 1 mês", + "title": "Cloud Login", + "trial_info": "Não são necessárias informações de pagamento" }, "register": { + "account_created": "Conta criada! Verifique o seu e-mail para instruções sobre como ativar a sua conta.", "create_account": "Criar conta", "email_address": "Endereço de e-mail", "email_error_msg": "E-mail inválido", @@ -1057,15 +1092,23 @@ "feature_remote_control": "Controlo do Home Assistant fora de casa", "feature_webhook_apps": "Fácil integração com aplicações baseadas no webhook, como o OwnTracks", "headline": "Inicie a sua avaliação gratuita", + "information": "Crie uma conta para iniciar a sua avaliação gratuita de um mês com o Home Assistant Cloud. Não são necessárias informações de pagamento.", "information2": "A avaliação gratuita dará acesso a todos os benefícios do Home Assistant Cloud, incluindo:", "information3": "Este serviço é executado pelo nosso parceiro", "information3a": ", uma empresa criada pelos fundadores do Home Assistant e do Hass.io.", + "information4": "Ao registrar uma conta, concorda com os seguintes termos e condições.", "link_privacy_policy": "Política de privacidade", "link_terms_conditions": "Termos e condições", "password": "Palavra-passe", "password_error_msg": "As palavras-passe têm pelo menos 8 caracteres", "resend_confirm_email": "Reenviar e-mail de confirmação", - "start_trial": "Iniciar avaliação" + "start_trial": "Iniciar avaliação", + "title": "Registar Conta" + } + }, + "common": { + "editor": { + "confirm_unsaved": "Existem alterações não guardadas. Tem a certeza de que quer sair?" } }, "core": { @@ -1165,6 +1208,7 @@ "description": "Visão geral de todas as entidades conhecidas.", "editor": { "confirm_delete": "Tem certeza de que deseja apagar esta entrada?", + "confirm_delete2": "Apagar uma entrada não removerá a entidade do Home Assistant. Para fazer isso,é necessário remover a integração '{platform}' do Home Assistant.", "default_name": "Nova Área", "delete": "APAGAR", "enabled_cause": "Desativado por {cause}.", @@ -1206,6 +1250,7 @@ "no_devices": "Esta integração não possui dispositivos.", "restart_confirm": "Reinicie o Home Assistant para concluir a remoção desta integração", "settings_button": "Editar configurações para {integration}", + "system_options_button": "Opções do sistema para {integration}", "via": "Ligado via" }, "config_flow": { @@ -1247,6 +1292,7 @@ "add_person": "Adicionar Pessoa", "caption": "Pessoas", "confirm_delete": "Tens a certeza que queres eliminar esta pessoa?", + "confirm_delete2": "Todos os dispositivos pertencentes a esta pessoa não ficarão atribuidos a ninguém.", "create_person": "Criar pessoa", "description": "Gerir as pessoas que o Home Assistant segue.", "detail": { @@ -1261,9 +1307,12 @@ "name": "Nome", "name_error_msg": "Nome é obrigatório", "new_person": "Nova Pessoa", + "no_device_tracker_available_intro": "Quando você possui dispositivos que indicam a presença de uma pessoa, poderá atribuí-los a essa pessoa aqui. Pode adicionar o seu primeiro dispositivo, adicionando uma integração de deteção de presença na página de integrações.", "update": "Atualizar" }, - "no_persons_created_yet": "Parece que você ainda não criou nenhuma pessoa." + "introduction": "Aqui pode definir cada pessoa de interesse no Home Assistant.", + "no_persons_created_yet": "Parece que você ainda não criou nenhuma pessoa.", + "note_about_persons_configured_in_yaml": "Nota: pessoas configuradas via configuration.yaml não podem ser editadas via UI." }, "scene": { "activated": "Ativar cena {name}.", @@ -1302,16 +1351,24 @@ "caption": "Script", "description": "Criar e editar scripts", "editor": { + "default_name": "Novo Script", + "delete_confirm": "Tem a certeza que quer apagar este script?", "delete_script": "Apagar script", + "header": "Script: {name}", "link_available_actions": "Saiba mais sobre ações disponíveis.", + "load_error_not_editable": "Apenas os scripts em scripts.yaml são editáveis.", "sequence": "Seqüência" }, "picker": { + "add_script": "Adicionar script", "edit_script": "Editar script", "header": "Editor de Script", "headers": { "name": "Nome" }, + "introduction": "O editor de scripts permite criar e editar scripts. Leia as instruções do link em baixo para se certificar de que configurou o Home Assistant corretamente.", + "learn_more": "Saber mais sobre scripts", + "no_scripts": "Não foi possível encontrar nenhum script editável", "show_info": "Mostrar informações sobre o script" } }, @@ -1397,12 +1454,20 @@ }, "caption": "ZHA", "cluster_attributes": { + "attributes_of_cluster": "Atributos do cluster selecionado", "get_zigbee_attribute": "Obter atributo Zigbee", + "header": "Atributos do cluster", + "help_attribute_dropdown": "Selecione um atributo para visualizar ou definir o seu valor.", "help_get_zigbee_attribute": "Obter o valor para o atributo selecionado.", + "help_set_zigbee_attribute": "Definir valor do atributo para o cluster especificado na entidade especificada.", + "introduction": "Ver e editar atributos do cluster.", "set_zigbee_attribute": "Definir atributo Zigbee" }, "cluster_commands": { + "commands_of_cluster": "Comandos do cluster selecionado", + "header": "Comandos de cluster", "help_command_dropdown": "Selecione um comando com o qual interagir.", + "introduction": "Ver e emitir comandos de cluster.", "issue_zigbee_command": "Emitir comando ZigBee" }, "common": { @@ -1424,7 +1489,10 @@ }, "node_management": { "header": "Gestão dispositivos", - "help_node_dropdown": "Selecione um dispositivo para visualizar as opções por dispositivo." + "help_node_dropdown": "Selecione um dispositivo para visualizar as opções por dispositivo.", + "hint_battery_devices": "Nota: Os dispositivos que entram em modo \"sleep\" (alimentados a bateria) precisam estar activos ao executar comandos sobre eles. Geralmente é possível \"acordar\" um dispositivo em modo\"sleep\" acionando-o.", + "hint_wakeup": "Alguns dispositivos, como os sensores Xiaomi, têm um botão de ativação que você pode pressionar em intervalos de ~ 5 segundos para manter os dispositivos acordados enquanto você interage com eles.", + "introduction": "Execute comandos ZHA que afetem um único dispositivo. Escolha um dispositivo para ver uma lista de comandos disponíveis." }, "services": { "reconfigure": "Reconfigure o dispositivo ZHA (curar dispositivo). Utilize isto se estiver a ter problemas com o dispositivo. Se o dispositivo em questão for um dispositivo alimentado por uma bateria, ao utilizar este serviço certifique-se de que o equipamento está ativo e a aceitar comandos.", @@ -1456,7 +1524,7 @@ "network_stopped": "Rede Z-Wave parada." }, "node_config": { - "config_parameter": "Configurar parâmetro", + "config_parameter": "Parâmetro de configuração", "config_value": "Cofigurar valor", "false": "Falso", "header": "Configurar opçoes do nó", @@ -1466,7 +1534,8 @@ "true": "Verdadeiro" }, "ozw_log": { - "header": "Log OZW" + "header": "Log OZW", + "introduction": "Veja o log. 0 é o mínimo (carrega o log inteiro) e 1000 é o máximo. Ao carregar irá ser mostrado um log estático e a cauda será atualizada automaticamente com o último número especificado de linhas do log." }, "services": { "add_node": "Adicionar nó", @@ -1474,7 +1543,7 @@ "cancel_command": "Cancelar comando", "heal_network": "Curar a Rede", "remove_node": "Remover nó", - "save_config": "Salvar configuração", + "save_config": "Guardar configuração", "soft_reset": "Reinicio suave", "start_network": "Iniciar a rede", "stop_network": "Parar a rede", @@ -1508,7 +1577,9 @@ }, "info": { "built_using": "Construído com", + "custom_uis": "IUs personalizados:", "frontend": "", + "frontend_version": "Versão frontend: {version} - {type}", "home_assistant_logo": "Logotipo do Home Assistant", "icons_by": "Ícones por", "lovelace_ui": "Ir para a UI Lovelace", @@ -1581,7 +1652,8 @@ "more_info": "Mostrar mais informações: {name}", "navigate_to": "Navegue até {location}", "tap": "Toque:", - "toggle": "Alternar {name}" + "toggle": "Alternar {name}", + "url": "Abrir janela para {url_path}" }, "shopping-list": { "add_item": "Adicionar Item", @@ -1614,7 +1686,8 @@ }, "entities": { "name": "Entidades", - "show_header_toggle": "Show Header Toggle?" + "show_header_toggle": "Show Header Toggle?", + "toggle": "Alternar entidades." }, "entity-button": { "name": "Botão Entidade" @@ -1689,6 +1762,9 @@ "media-control": { "name": "Controlo multimédia" }, + "picture-elements": { + "name": "Elementos da imagem" + }, "picture-entity": { "name": "Entidade de imagem" }, @@ -1979,6 +2055,7 @@ }, "profile": { "advanced_mode": { + "description": "Desbloqueia funcionalidades avançadas.", "title": "Modo avançado" }, "change_password": { diff --git a/translations/ru.json b/translations/ru.json index 4c9bc4c9b6..e3d3e2fbf2 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -1337,7 +1337,7 @@ "delete": "Удалить", "description": "Управляйте подключенными устройствами", "details": "Здесь приведена вся доступная информация об этом устройстве.", - "device_not_found": "Устройство не найдено.", + "device_not_found": "Устройство не найдено", "entities": { "add_entities_lovelace": "Добавить объекты в Lovelace UI", "entities": "Объекты", @@ -1776,7 +1776,7 @@ "caption": "Добавить устройства", "description": "Добавить устройства в сеть Zigbee" }, - "caption": "ZHA", + "caption": "Zigbee Home Automation", "cluster_attributes": { "attributes_of_cluster": "Атрибуты выбранного кластера", "get_zigbee_attribute": "Получить атрибут Zigbee", diff --git a/translations/zh-Hans.json b/translations/zh-Hans.json index e58cf0aef6..4ca86f4f2e 100644 --- a/translations/zh-Hans.json +++ b/translations/zh-Hans.json @@ -758,11 +758,13 @@ "buttons": { "add": "添加设备", "reconfigure": "重新配置设备", - "remove": "删除设备" + "remove": "删除设备", + "zigbee_information": "Zigbee 信息" }, "confirmations": { "remove": "您确定要删除此设备吗?" }, + "device_signature": "Zigbee 设备签名", "last_seen": "上次看到", "manuf": "制造商:{manufacturer}", "no_area": "没有区域", @@ -771,7 +773,8 @@ "services": { "reconfigure": "这将重新配置 ZHA 设备(复原设备)。如果您的设备遇到问题,请使用此项。如果有问题的设备是由电池供电的,请确保在使用此服务时它处于唤醒状态并可以接受指令。", "remove": "从 Zigbee 网络中删除设备。", - "updateDeviceName": "在设备注册表中为此设备设置自定义名称。" + "updateDeviceName": "在设备注册表中为此设备设置自定义名称。", + "zigbee_information": "查看设备的 Zigbee 信息。" }, "unknown": "未知", "zha_device_card": { From d45a6746523f4f76b7319fd6089fba93d5295d30 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 18 Apr 2020 17:14:25 -0700 Subject: [PATCH 17/36] Ask specific translations (#5560) --- build-scripts/webpack.js | 4 + demo/src/stubs/lovelace.ts | 1 + demo/src/stubs/translations.ts | 469 +----------------- src/data/config_flow.ts | 3 +- src/data/translation.ts | 25 + .../config-flow/show-dialog-config-flow.ts | 35 +- .../config-flow/show-dialog-options-flow.ts | 16 +- .../config-flow/step-flow-pick-handler.ts | 50 +- src/layouts/home-assistant.ts | 6 + src/onboarding/action-badge.ts | 89 ++++ src/onboarding/ha-onboarding.ts | 9 + src/onboarding/integration-badge.ts | 25 +- src/onboarding/onboarding-integrations.ts | 29 +- .../config/automation/ha-config-automation.ts | 5 + src/panels/config/ha-panel-config.ts | 1 + .../integrations/ha-config-integrations.ts | 8 + src/panels/config/script/ha-config-script.ts | 5 + .../ha-panel-developer-tools.ts | 5 + src/panels/logbook/ha-panel-logbook.js | 5 + .../profile/ha-mfa-module-setup-flow.js | 1 + src/state/connection-mixin.ts | 8 + src/state/translations-mixin.ts | 114 ++++- src/types.ts | 7 + 23 files changed, 397 insertions(+), 523 deletions(-) create mode 100644 src/onboarding/action-badge.ts diff --git a/build-scripts/webpack.js b/build-scripts/webpack.js index 07894ad874..e5207878d8 100644 --- a/build-scripts/webpack.js +++ b/build-scripts/webpack.js @@ -70,6 +70,7 @@ const createWebpackConfig = ({ __BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"), __VERSION__: JSON.stringify(version), __DEMO__: false, + __BACKWARDS_COMPAT__: false, __STATIC_PATH__: "/static/", "process.env.NODE_ENV": JSON.stringify( isProdBuild ? "production" : "development" @@ -221,6 +222,9 @@ const createCastConfig = ({ isProdBuild, latestBuild }) => { outputRoot: paths.cast_root, isProdBuild, latestBuild, + defineOverlay: { + __BACKWARDS_COMPAT__: true, + }, }); }; diff --git a/demo/src/stubs/lovelace.ts b/demo/src/stubs/lovelace.ts index 3928e5eaf0..74a38bc428 100644 --- a/demo/src/stubs/lovelace.ts +++ b/demo/src/stubs/lovelace.ts @@ -17,6 +17,7 @@ export const mockLovelace = ( ); hass.mockWS("lovelace/config/save", () => Promise.resolve()); + hass.mockWS("lovelace/resources", () => Promise.resolve([])); }; customElements.whenDefined("hui-view").then(() => { diff --git a/demo/src/stubs/translations.ts b/demo/src/stubs/translations.ts index 615159343d..f654f19fc7 100644 --- a/demo/src/stubs/translations.ts +++ b/demo/src/stubs/translations.ts @@ -2,473 +2,6 @@ import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; export const mockTranslations = (hass: MockHomeAssistant) => { hass.mockWS("frontend/get_translations", () => ({ - resources: { - "component.lifx.config.abort.no_devices_found": - "No LIFX devices found on the network.", - "component.lifx.config.abort.single_instance_allowed": - "Only a single configuration of LIFX is possible.", - "component.lifx.config.step.confirm.description": - "Do you want to set up LIFX?", - "component.lifx.config.step.confirm.title": "LIFX", - "component.lifx.config.title": "LIFX", - "component.hangouts.config.abort.already_configured": - "Google Hangouts is already configured", - "component.hangouts.config.abort.unknown": "Unknown error occurred.", - "component.hangouts.config.error.invalid_2fa": - "Invalid 2 Factor Authentication, please try again.", - "component.hangouts.config.error.invalid_2fa_method": - "Invalid 2FA Method (Verify on Phone).", - "component.hangouts.config.error.invalid_login": - "Invalid Login, please try again.", - "component.hangouts.config.step.2fa.data.2fa": "2FA Pin", - "component.hangouts.config.step.2fa.title": "2-Factor-Authentication", - "component.hangouts.config.step.user.data.email": "E-Mail Address", - "component.hangouts.config.step.user.data.password": "Password", - "component.hangouts.config.step.user.title": "Google Hangouts Login", - "component.hangouts.config.title": "Google Hangouts", - "component.rainmachine.config.error.identifier_exists": - "Account already registered", - "component.rainmachine.config.error.invalid_credentials": - "Invalid credentials", - "component.rainmachine.config.step.user.data.ip_address": - "Hostname or IP Address", - "component.rainmachine.config.step.user.data.password": "Password", - "component.rainmachine.config.step.user.data.port": "Port", - "component.rainmachine.config.step.user.title": - "Fill in your information", - "component.rainmachine.config.title": "RainMachine", - "component.homematicip_cloud.config.abort.already_configured": - "Access point is already configured", - "component.homematicip_cloud.config.abort.connection_aborted": - "Could not connect to HMIP server", - "component.homematicip_cloud.config.abort.unknown": - "Unknown error occurred.", - "component.homematicip_cloud.config.error.invalid_pin": - "Invalid PIN, please try again.", - "component.homematicip_cloud.config.error.press_the_button": - "Please press the blue button.", - "component.homematicip_cloud.config.error.register_failed": - "Failed to register, please try again.", - "component.homematicip_cloud.config.error.timeout_button": - "Blue button press timeout, please try again.", - "component.homematicip_cloud.config.step.init.data.hapid": - "Access point ID (SGTIN)", - "component.homematicip_cloud.config.step.init.data.name": - "Name (optional, used as name prefix for all devices)", - "component.homematicip_cloud.config.step.init.data.pin": - "Pin Code (optional)", - "component.homematicip_cloud.config.step.init.title": - "Pick HomematicIP Access point", - "component.homematicip_cloud.config.step.link.description": - "Press the blue button on the access point and the submit button to register HomematicIP with Home Assistant.\n\n![Location of button on bridge](/static/images/config_flows/config_homematicip_cloud.png)", - "component.homematicip_cloud.config.step.link.title": "Link Access point", - "component.homematicip_cloud.config.title": "HomematicIP Cloud", - "component.daikin.config.abort.already_configured": - "Device is already configured", - "component.daikin.config.abort.device_fail": - "Unexpected error creating device.", - "component.daikin.config.abort.device_timeout": - "Timeout connecting to the device.", - "component.daikin.config.step.user.data.host": "Host", - "component.daikin.config.step.user.description": - "Enter IP address of your Daikin AC.", - "component.daikin.config.step.user.title": "Configure Daikin AC", - "component.daikin.config.title": "Daikin AC", - "component.unifi.config.abort.already_configured": - "Controller site is already configured", - "component.unifi.config.abort.user_privilege": - "User needs to be administrator", - "component.unifi.config.error.faulty_credentials": "Bad user credentials", - "component.unifi.config.error.service_unavailable": - "No service available", - "component.unifi.config.step.user.data.host": "Host", - "component.unifi.config.step.user.data.password": "Password", - "component.unifi.config.step.user.data.port": "Port", - "component.unifi.config.step.user.data.site": "Site ID", - "component.unifi.config.step.user.data.username": "User name", - "component.unifi.config.step.user.data.verify_ssl": - "Controller using proper certificate", - "component.unifi.config.step.user.title": "Set up UniFi Controller", - "component.unifi.config.title": "UniFi Controller", - "component.nest.config.abort.already_setup": - "You can only configure a single Nest account.", - "component.nest.config.abort.authorize_url_fail": - "Unknown error generating an authorize url.", - "component.nest.config.abort.authorize_url_timeout": - "Timeout generating authorize url.", - "component.nest.config.abort.no_flows": - "You need to configure Nest before being able to authenticate with it. [Please read the instructions](https://www.home-assistant.io/integrations/nest/).", - "component.nest.config.error.internal_error": - "Internal error validating code", - "component.nest.config.error.invalid_code": "Invalid code", - "component.nest.config.error.timeout": "Timeout validating code", - "component.nest.config.error.unknown": "Unknown error validating code", - "component.nest.config.step.init.data.flow_impl": "Provider", - "component.nest.config.step.init.description": - "Pick via which authentication provider you want to authenticate with Nest.", - "component.nest.config.step.init.title": "Authentication Provider", - "component.nest.config.step.link.data.code": "Pin code", - "component.nest.config.step.link.description": - "To link your Nest account, [authorize your account]({url}).\n\nAfter authorization, copy-paste the provided pin code below.", - "component.nest.config.step.link.title": "Link Nest Account", - "component.nest.config.title": "Nest", - "component.mailgun.config.abort.not_internet_accessible": - "Your Home Assistant instance needs to be accessible from the internet to receive Mailgun messages.", - "component.mailgun.config.abort.one_instance_allowed": - "Only a single instance is necessary.", - "component.mailgun.config.create_entry.default": - "To send events to Home Assistant, you will need to setup [Webhooks with Mailgun]({mailgun_url}).\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\nSee [the documentation]({docs_url}) on how to configure automations to handle incoming data.", - "component.mailgun.config.step.user.description": - "Are you sure you want to set up Mailgun?", - "component.mailgun.config.step.user.title": "Set up the Mailgun Webhook", - "component.mailgun.config.title": "Mailgun", - "component.tellduslive.config.abort.already_setup": - "TelldusLive is already configured", - "component.tellduslive.config.abort.authorize_url_fail": - "Unknown error generating an authorize url.", - "component.tellduslive.config.abort.authorize_url_timeout": - "Timeout generating authorize url.", - "component.tellduslive.config.abort.unknown": "Unknown error occurred", - "component.tellduslive.config.error.auth_error": - "Authentication error, please try again", - "component.tellduslive.config.step.auth.description": - "To link your TelldusLive account:\n 1. Click the link below\n 2. Login to Telldus Live\n 3. Authorize **{app_name}** (click **Yes**).\n 4. Come back here and click **SUBMIT**.\n\n [Link TelldusLive account]({auth_url})", - "component.tellduslive.config.step.auth.title": - "Authenticate against TelldusLive", - "component.tellduslive.config.step.user.data.host": "Host", - "component.tellduslive.config.step.user.title": "Pick endpoint.", - "component.tellduslive.config.title": "Telldus Live", - "component.esphome.config.abort.already_configured": - "ESP is already configured", - "component.esphome.config.error.connection_error": - "Can't connect to ESP. Please make sure your YAML file contains an 'api:' line.", - "component.esphome.config.error.invalid_password": "Invalid password!", - "component.esphome.config.error.resolve_error": - "Can't resolve address of the ESP. If this error persists, please set a static IP address: https://esphomelib.com/esphomeyaml/components/wifi.html#manual-ips", - "component.esphome.config.step.authenticate.data.password": "Password", - "component.esphome.config.step.authenticate.description": - "Please enter the password you set in your configuration.", - "component.esphome.config.step.authenticate.title": "Enter Password", - "component.esphome.config.step.user.data.host": "Host", - "component.esphome.config.step.user.data.port": "Port", - "component.esphome.config.step.user.description": - "Please enter connection settings of your [ESPHome](https://esphomelib.com/) node.", - "component.esphome.config.step.user.title": "ESPHome", - "component.esphome.config.title": "ESPHome", - "component.luftdaten.config.error.communication_error": - "Unable to communicate with the Luftdaten API", - "component.luftdaten.config.error.invalid_sensor": - "Sensor not available or invalid", - "component.luftdaten.config.error.sensor_exists": - "Sensor already registered", - "component.luftdaten.config.step.user.data.show_on_map": "Show on map", - "component.luftdaten.config.step.user.data.station_id": - "Luftdaten Sensor ID", - "component.luftdaten.config.step.user.title": "Define Luftdaten", - "component.luftdaten.config.title": "Luftdaten", - "component.upnp.config.abort.already_configured": - "UPnP/IGD is already configured", - "component.upnp.config.abort.incomplete_device": - "Ignoring incomplete UPnP device", - "component.upnp.config.abort.no_devices_discovered": - "No UPnP/IGDs discovered", - "component.upnp.config.abort.no_devices_found": - "No UPnP/IGD devices found on the network.", - "component.upnp.config.abort.no_sensors_or_port_mapping": - "Enable at least sensors or port mapping", - "component.upnp.config.abort.single_instance_allowed": - "Only a single configuration of UPnP/IGD is necessary.", - "component.upnp.config.step.confirm.description": - "Do you want to set up UPnP/IGD?", - "component.upnp.config.step.confirm.title": "UPnP/IGD", - "component.upnp.config.step.init.title": "UPnP/IGD", - "component.upnp.config.step.user.data.enable_port_mapping": - "Enable port mapping for Home Assistant", - "component.upnp.config.step.user.data.enable_sensors": - "Add traffic sensors", - "component.upnp.config.step.user.data.igd": "UPnP/IGD", - "component.upnp.config.step.user.title": - "Configuration options for the UPnP/IGD", - "component.upnp.config.title": "UPnP/IGD", - "component.point.config.abort.already_setup": - "You can only configure a Point account.", - "component.point.config.abort.authorize_url_fail": - "Unknown error generating an authorize url.", - "component.point.config.abort.authorize_url_timeout": - "Timeout generating authorize url.", - "component.point.config.abort.external_setup": - "Point successfully configured from another flow.", - "component.point.config.abort.no_flows": - "You need to configure Point before being able to authenticate with it. [Please read the instructions](https://www.home-assistant.io/integrations/point/).", - "component.point.config.create_entry.default": - "Successfully authenticated with Minut for your Point device(s)", - "component.point.config.error.follow_link": - "Please follow the link and authenticate before pressing Submit", - "component.point.config.error.no_token": "Not authenticated with Minut", - "component.point.config.step.auth.description": - "Please follow the link below and Accept access to your Minut account, then come back and press Submit below.\n\n[Link]({authorization_url})", - "component.point.config.step.auth.title": "Authenticate Point", - "component.point.config.step.user.data.flow_impl": "Provider", - "component.point.config.step.user.description": - "Pick via which authentication provider you want to authenticate with Point.", - "component.point.config.step.user.title": "Authentication Provider", - "component.point.config.title": "Minut Point", - "component.auth.mfa_setup.notify.abort.no_available_service": - "No notification services available.", - "component.auth.mfa_setup.notify.error.invalid_code": - "Invalid code, please try again.", - "component.auth.mfa_setup.notify.step.init.description": - "Please select one of the notification services:", - "component.auth.mfa_setup.notify.step.init.title": - "Set up one-time password delivered by notify component", - "component.auth.mfa_setup.notify.step.setup.description": - "A one-time password has been sent via **notify.{notify_service}**. Please enter it below:", - "component.auth.mfa_setup.notify.step.setup.title": "Verify setup", - "component.auth.mfa_setup.notify.title": "Notify One-Time Password", - "component.auth.mfa_setup.totp.error.invalid_code": - "Invalid code, please try again. If you get this error consistently, please make sure the clock of your Home Assistant system is accurate.", - "component.auth.mfa_setup.totp.step.init.description": - "To activate two factor authentication using time-based one-time passwords, scan the QR code with your authentication app. If you don't have one, we recommend either [Google Authenticator](https://support.google.com/accounts/answer/1066447) or [Authy](https://authy.com/).\n\n{qr_code}\n\nAfter scanning the code, enter the six digit code from your app to verify the setup. If you have problems scanning the QR code, do a manual setup with code **`{code}`**.", - "component.auth.mfa_setup.totp.step.init.title": - "Set up two-factor authentication using TOTP", - "component.auth.mfa_setup.totp.title": "TOTP", - "component.emulated_roku.config.abort.name_exists": "Name already exists", - "component.emulated_roku.config.step.user.data.advertise_ip": - "Advertise IP", - "component.emulated_roku.config.step.user.data.advertise_port": - "Advertise port", - "component.emulated_roku.config.step.user.data.host_ip": "Host IP", - "component.emulated_roku.config.step.user.data.listen_port": - "Listen port", - "component.emulated_roku.config.step.user.data.name": "Name", - "component.emulated_roku.config.step.user.data.upnp_bind_multicast": - "Bind multicast (True/False)", - "component.emulated_roku.config.step.user.title": - "Define server configuration", - "component.emulated_roku.config.title": "EmulatedRoku", - "component.owntracks.config.abort.one_instance_allowed": - "Only a single instance is necessary.", - "component.owntracks.config.create_entry.default": - "\n\nOn Android, open [the OwnTracks app]({android_url}), go to preferences -> connection. Change the following settings:\n - Mode: Private HTTP\n - Host: {webhook_url}\n - Identification:\n - Username: ``\n - Device ID: ``\n\nOn iOS, open [the OwnTracks app]({ios_url}), tap (i) icon in top left -> settings. Change the following settings:\n - Mode: HTTP\n - URL: {webhook_url}\n - Turn on authentication\n - UserID: ``\n\n{secret}\n\nSee [the documentation]({docs_url}) for more information.", - "component.owntracks.config.step.user.description": - "Are you sure you want to set up OwnTracks?", - "component.owntracks.config.step.user.title": "Set up OwnTracks", - "component.owntracks.config.title": "OwnTracks", - "component.zone.config.error.name_exists": "Name already exists", - "component.zone.config.step.init.data.icon": "Icon", - "component.zone.config.step.init.data.latitude": "Latitude", - "component.zone.config.step.init.data.longitude": "Longitude", - "component.zone.config.step.init.data.name": "Name", - "component.zone.config.step.init.data.passive": "Passive", - "component.zone.config.step.init.data.radius": "Radius", - "component.zone.config.step.init.title": "Define zone parameters", - "component.zone.config.title": "Zone", - "component.hue.config.abort.all_configured": - "All Philips Hue bridges are already configured", - "component.hue.config.abort.already_configured": - "Bridge is already configured", - "component.hue.config.abort.cannot_connect": - "Unable to connect to the bridge", - "component.hue.config.abort.discover_timeout": - "Unable to discover Hue bridges", - "component.hue.config.abort.no_bridges": - "No Philips Hue bridges discovered", - "component.hue.config.abort.unknown": "Unknown error occurred", - "component.hue.config.error.linking": "Unknown linking error occurred.", - "component.hue.config.error.register_failed": - "Failed to register, please try again", - "component.hue.config.step.init.data.host": "Host", - "component.hue.config.step.init.title": "Pick Hue bridge", - "component.hue.config.step.link.description": - "Press the button on the bridge to register Philips Hue with Home Assistant.\n\n![Location of button on bridge](/static/images/config_philips_hue.jpg)", - "component.hue.config.step.link.title": "Link Hub", - "component.hue.config.title": "Philips Hue", - "component.tradfri.config.abort.already_configured": - "Bridge is already configured", - "component.tradfri.config.error.cannot_connect": - "Unable to connect to the gateway.", - "component.tradfri.config.error.invalid_key": - "Failed to register with provided key. If this keeps happening, try restarting the gateway.", - "component.tradfri.config.error.timeout": "Timeout validating the code.", - "component.tradfri.config.step.auth.data.host": "Host", - "component.tradfri.config.step.auth.data.security_code": "Security Code", - "component.tradfri.config.step.auth.description": - "You can find the security code on the back of your gateway.", - "component.tradfri.config.step.auth.title": "Enter security code", - "component.tradfri.config.title": "IKEA TRÅDFRI", - "component.mqtt.config.abort.single_instance_allowed": - "Only a single configuration of MQTT is allowed.", - "component.mqtt.config.error.cannot_connect": - "Unable to connect to the broker.", - "component.mqtt.config.step.broker.data.broker": "Broker", - "component.mqtt.config.step.broker.data.discovery": "Enable discovery", - "component.mqtt.config.step.broker.data.password": "Password", - "component.mqtt.config.step.broker.data.port": "Port", - "component.mqtt.config.step.broker.data.username": "Username", - "component.mqtt.config.step.broker.description": - "Please enter the connection information of your MQTT broker.", - "component.mqtt.config.step.broker.title": "MQTT", - "component.mqtt.config.step.hassio_confirm.data.discovery": - "Enable discovery", - "component.mqtt.config.step.hassio_confirm.description": - "Do you want to configure Home Assistant to connect to the MQTT broker provided by the hass.io add-on {addon}?", - "component.mqtt.config.step.hassio_confirm.title": - "MQTT Broker via Hass.io add-on", - "component.mqtt.config.title": "MQTT", - "component.geofency.config.abort.not_internet_accessible": - "Your Home Assistant instance needs to be accessible from the internet to receive messages from Geofency.", - "component.geofency.config.abort.one_instance_allowed": - "Only a single instance is necessary.", - "component.geofency.config.create_entry.default": - "To send events to Home Assistant, you will need to setup the webhook feature in Geofency.\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n\nSee [the documentation]({docs_url}) for further details.", - "component.geofency.config.step.user.description": - "Are you sure you want to set up the Geofency Webhook?", - "component.geofency.config.step.user.title": - "Set up the Geofency Webhook", - "component.geofency.config.title": "Geofency Webhook", - "component.simplisafe.config.error.identifier_exists": - "Account already registered", - "component.simplisafe.config.error.invalid_credentials": - "Invalid credentials", - "component.simplisafe.config.step.user.data.code": - "Code (for Home Assistant)", - "component.simplisafe.config.step.user.data.password": "Password", - "component.simplisafe.config.step.user.data.username": "Email Address", - "component.simplisafe.config.step.user.title": "Fill in your information", - "component.simplisafe.config.title": "SimpliSafe", - "component.dialogflow.config.abort.not_internet_accessible": - "Your Home Assistant instance needs to be accessible from the internet to receive Dialogflow messages.", - "component.dialogflow.config.abort.one_instance_allowed": - "Only a single instance is necessary.", - "component.dialogflow.config.create_entry.default": - "To send events to Home Assistant, you will need to setup [webhook integration of Dialogflow]({dialogflow_url}).\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\nSee [the documentation]({docs_url}) for further details.", - "component.dialogflow.config.step.user.description": - "Are you sure you want to set up Dialogflow?", - "component.dialogflow.config.step.user.title": - "Set up the Dialogflow Webhook", - "component.dialogflow.config.title": "Dialogflow", - "component.deconz.config.abort.already_configured": - "Bridge is already configured", - "component.deconz.config.abort.no_bridges": - "No deCONZ bridges discovered", - "component.deconz.config.abort.one_instance_only": - "Component only supports one deCONZ instance", - "component.deconz.config.error.no_key": "Couldn't get an API key", - "component.deconz.config.step.init.data.host": "Host", - "component.deconz.config.step.init.data.port": "Port", - "component.deconz.config.step.init.title": "Define deCONZ gateway", - "component.deconz.config.step.link.description": - 'Unlock your deCONZ gateway to register with Home Assistant.\n\n1. Go to deCONZ system settings\n2. Press "Unlock Gateway" button', - "component.deconz.config.step.link.title": "Link with deCONZ", - "component.deconz.config.step.options.data.allow_clip_sensor": - "Allow importing virtual sensors", - "component.deconz.config.step.options.data.allow_deconz_groups": - "Allow importing deCONZ groups", - "component.deconz.config.step.options.title": - "Extra configuration options for deCONZ", - "component.deconz.config.title": "deCONZ Zigbee gateway", - "component.openuv.config.error.identifier_exists": - "Coordinates already registered", - "component.openuv.config.error.invalid_api_key": "Invalid API key", - "component.openuv.config.step.user.data.api_key": "OpenUV API Key", - "component.openuv.config.step.user.data.elevation": "Elevation", - "component.openuv.config.step.user.data.latitude": "Latitude", - "component.openuv.config.step.user.data.longitude": "Longitude", - "component.openuv.config.step.user.title": "Fill in your information", - "component.openuv.config.title": "OpenUV", - "component.locative.config.title": "Locative Webhook", - "component.locative.config.step.user.title": - "Set up the Locative Webhook", - "component.locative.config.step.user.description": - "Are you sure you want to set up the Locative Webhook?", - "component.locative.config.abort.one_instance_allowed": - "Only a single instance is necessary.", - "component.locative.config.abort.not_internet_accessible": - "Your Home Assistant instance needs to be accessible from the internet to receive messages from Geofency.", - "component.locative.config.create_entry.default": - "To send locations to Home Assistant, you will need to setup the webhook feature in the Locative app.\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n\nSee [the documentation]({docs_url}) for further details.", - "component.ios.config.abort.single_instance_allowed": - "Only a single configuration of Home Assistant iOS is necessary.", - "component.ios.config.step.confirm.description": - "Do you want to set up the Home Assistant iOS component?", - "component.ios.config.step.confirm.title": "Home Assistant iOS", - "component.ios.config.title": "Home Assistant iOS", - "component.smhi.config.error.name_exists": "Name already exists", - "component.smhi.config.error.wrong_location": "Location Sweden only", - "component.smhi.config.step.user.data.latitude": "Latitude", - "component.smhi.config.step.user.data.longitude": "Longitude", - "component.smhi.config.step.user.data.name": "Name", - "component.smhi.config.step.user.title": "Location in Sweden", - "component.smhi.config.title": "Swedish weather service (SMHI)", - "component.sonos.config.abort.no_devices_found": - "No Sonos devices found on the network.", - "component.sonos.config.abort.single_instance_allowed": - "Only a single configuration of Sonos is necessary.", - "component.sonos.config.step.confirm.description": - "Do you want to set up Sonos?", - "component.sonos.config.step.confirm.title": "Sonos", - "component.sonos.config.title": "Sonos", - "component.ifttt.config.abort.not_internet_accessible": - "Your Home Assistant instance needs to be accessible from the internet to receive IFTTT messages.", - "component.ifttt.config.abort.one_instance_allowed": - "Only a single instance is necessary.", - "component.ifttt.config.create_entry.default": - 'To send events to Home Assistant, you will need to use the "Make a web request" action from the [IFTTT Webhook applet]({applet_url}).\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\nSee [the documentation]({docs_url}) on how to configure automations to handle incoming data.', - "component.ifttt.config.step.user.description": - "Are you sure you want to set up IFTTT?", - "component.ifttt.config.step.user.title": - "Set up the IFTTT Webhook Applet", - "component.ifttt.config.title": "IFTTT", - "component.twilio.config.abort.not_internet_accessible": - "Your Home Assistant instance needs to be accessible from the internet to receive Twilio messages.", - "component.twilio.config.abort.one_instance_allowed": - "Only a single instance is necessary.", - "component.twilio.config.create_entry.default": - "To send events to Home Assistant, you will need to setup [Webhooks with Twilio]({twilio_url}).\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/x-www-form-urlencoded\n\nSee [the documentation]({docs_url}) on how to configure automations to handle incoming data.", - "component.twilio.config.step.user.description": - "Are you sure you want to set up Twilio?", - "component.twilio.config.step.user.title": "Set up the Twilio Webhook", - "component.twilio.config.title": "Twilio", - "component.zha.config.abort.single_instance_allowed": - "Only a single configuration of ZHA is allowed.", - "component.zha.config.error.cannot_connect": - "Unable to connect to ZHA device.", - "component.zha.config.step.user.data.radio_type": "Radio Type", - "component.zha.config.step.user.data.usb_path": "USB Device Path", - "component.zha.config.step.user.title": "ZHA", - "component.zha.config.title": "ZHA", - "component.gpslogger.config.title": "GPSLogger Webhook", - "component.gpslogger.config.step.user.title": - "Set up the GPSLogger Webhook", - "component.gpslogger.config.step.user.description": - "Are you sure you want to set up the GPSLogger Webhook?", - "component.gpslogger.config.abort.one_instance_allowed": - "Only a single instance is necessary.", - "component.gpslogger.config.abort.not_internet_accessible": - "Your Home Assistant instance needs to be accessible from the internet to receive messages from GPSLogger.", - "component.gpslogger.config.create_entry.default": - "To send events to Home Assistant, you will need to setup the webhook feature in GPSLogger.\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n\nSee [the documentation]({docs_url}) for further details.", - "component.zwave.config.abort.already_configured": - "Z-Wave is already configured", - "component.zwave.config.abort.one_instance_only": - "Component only supports one Z-Wave instance", - "component.zwave.config.error.option_error": - "Z-Wave validation failed. Is the path to the USB stick correct?", - "component.zwave.config.step.user.data.network_key": - "Network Key (leave blank to auto-generate)", - "component.zwave.config.step.user.data.usb_path": "USB Path", - "component.zwave.config.step.user.description": - "See https://www.home-assistant.io/docs/z-wave/installation/ for information on the configuration variables", - "component.zwave.config.step.user.title": "Set up Z-Wave", - "component.zwave.config.title": "Z-Wave", - "component.cast.config.abort.no_devices_found": - "No Google Cast devices found on the network.", - "component.cast.config.abort.single_instance_allowed": - "Only a single configuration of Google Cast is necessary.", - "component.cast.config.step.confirm.description": - "Do you want to set up Google Cast?", - "component.cast.config.step.confirm.title": "Google Cast", - "component.cast.config.title": "Google Cast", - }, + resources: {}, })); }; diff --git a/src/data/config_flow.ts b/src/data/config_flow.ts index 288803a715..fb256ec0fa 100644 --- a/src/data/config_flow.ts +++ b/src/data/config_flow.ts @@ -3,6 +3,7 @@ import { LocalizeFunc } from "../common/translations/localize"; import { debounce } from "../common/util/debounce"; import { HomeAssistant } from "../types"; import { DataEntryFlowProgress, DataEntryFlowStep } from "./data_entry_flow"; +import { domainToName } from "./integration"; export const DISCOVERY_SOURCES = ["unignore", "homekit", "ssdp", "zeroconf"]; @@ -75,7 +76,7 @@ export const localizeConfigFlowTitle = ( const placeholders = flow.context.title_placeholders || {}; const placeholderKeys = Object.keys(placeholders); if (placeholderKeys.length === 0) { - return localize(`component.${flow.handler}.title`); + return domainToName(localize, flow.handler); } const args: string[] = []; placeholderKeys.forEach((key) => { diff --git a/src/data/translation.ts b/src/data/translation.ts index f2ce1a7c1a..a713ccd256 100644 --- a/src/data/translation.ts +++ b/src/data/translation.ts @@ -11,6 +11,14 @@ declare global { } } +export type TranslationCategory = + | "title" + | "state" + | "config" + | "options" + | "device_automation" + | "mfa_setup"; + export const fetchTranslationPreferences = (hass: HomeAssistant) => fetchFrontendUserData(hass.connection, "language"); @@ -20,6 +28,23 @@ export const saveTranslationPreferences = ( ) => saveFrontendUserData(hass.connection, "language", data); export const getHassTranslations = async ( + hass: HomeAssistant, + language: string, + category: TranslationCategory, + integration?: string, + config_flow?: boolean +): Promise<{}> => { + const result = await hass.callWS<{ resources: {} }>({ + type: "frontend/get_translations", + language, + category, + integration, + config_flow, + }); + return result.resources; +}; + +export const getHassTranslationsPre109 = async ( hass: HomeAssistant, language: string ): Promise<{}> => { diff --git a/src/dialogs/config-flow/show-dialog-config-flow.ts b/src/dialogs/config-flow/show-dialog-config-flow.ts index 0a2d6341e2..27c4e8706d 100644 --- a/src/dialogs/config-flow/show-dialog-config-flow.ts +++ b/src/dialogs/config-flow/show-dialog-config-flow.ts @@ -13,6 +13,7 @@ import { loadDataEntryFlowDialog, showFlowDialog, } from "./show-dialog-data-entry-flow"; +import { domainToName } from "../../data/integration"; export const loadConfigFlowDialog = loadDataEntryFlowDialog; @@ -22,17 +23,31 @@ export const showConfigFlowDialog = ( ): void => showFlowDialog(element, dialogParams, { loadDevicesAndAreas: true, - getFlowHandlers: (hass) => - getConfigFlowHandlers(hass).then((handlers) => - handlers.sort((handlerA, handlerB) => - caseInsensitiveCompare( - hass.localize(`component.${handlerA}.title`), - hass.localize(`component.${handlerB}.title`) - ) + getFlowHandlers: async (hass) => { + const [handlers] = await Promise.all([ + getConfigFlowHandlers(hass), + hass.loadBackendTranslation("title", undefined, true), + ]); + + return handlers.sort((handlerA, handlerB) => + caseInsensitiveCompare( + domainToName(hass.localize, handlerA), + domainToName(hass.localize, handlerB) ) - ), - createFlow: createConfigFlow, - fetchFlow: fetchConfigFlow, + ); + }, + createFlow: async (hass, handler) => { + const [step] = await Promise.all([ + createConfigFlow(hass, handler), + hass.loadBackendTranslation("config", handler), + ]); + return step; + }, + fetchFlow: async (hass, flowId) => { + const step = await fetchConfigFlow(hass, flowId); + await hass.loadBackendTranslation("config", step.handler); + return step; + }, handleFlowStep: handleConfigFlowStep, deleteFlow: deleteConfigFlow, diff --git a/src/dialogs/config-flow/show-dialog-options-flow.ts b/src/dialogs/config-flow/show-dialog-options-flow.ts index d2ccebecc2..3df7e19f2d 100644 --- a/src/dialogs/config-flow/show-dialog-options-flow.ts +++ b/src/dialogs/config-flow/show-dialog-options-flow.ts @@ -25,8 +25,20 @@ export const showOptionsFlowDialog = ( }, { loadDevicesAndAreas: false, - createFlow: createOptionsFlow, - fetchFlow: fetchOptionsFlow, + createFlow: async (hass, handler) => { + const [step] = await Promise.all([ + createOptionsFlow(hass, handler), + hass.loadBackendTranslation("options", configEntry.domain), + ]); + return step; + }, + fetchFlow: async (hass, flowId) => { + const [step] = await Promise.all([ + fetchOptionsFlow(hass, flowId), + hass.loadBackendTranslation("options", configEntry.domain), + ]); + return step; + }, handleFlowStep: handleOptionsFlowStep, deleteFlow: deleteOptionsFlow, diff --git a/src/dialogs/config-flow/step-flow-pick-handler.ts b/src/dialogs/config-flow/step-flow-pick-handler.ts index dfdddace6a..bf7a64c585 100644 --- a/src/dialogs/config-flow/step-flow-pick-handler.ts +++ b/src/dialogs/config-flow/step-flow-pick-handler.ts @@ -20,6 +20,8 @@ import "../../components/ha-icon-next"; import { HomeAssistant } from "../../types"; import { FlowConfig } from "./show-dialog-data-entry-flow"; import { configFlowContentStyles } from "./styles"; +import { domainToName } from "../../data/integration"; +import { LocalizeFunc } from "../../common/translations/localize"; interface HandlerObj { name: string; @@ -40,31 +42,37 @@ class StepFlowPickHandler extends LitElement { private _width?: number; - private _getHandlers = memoizeOne((h: string[], filter?: string) => { - const handlers: HandlerObj[] = h.map((handler) => { - return { - name: this.hass.localize(`component.${handler}.title`) || handler, - slug: handler, - }; - }); + private _getHandlers = memoizeOne( + (h: string[], filter?: string, _localize?: LocalizeFunc) => { + const handlers: HandlerObj[] = h.map((handler) => { + return { + name: domainToName(this.hass.localize, handler), + slug: handler, + }; + }); - if (filter) { - const options: Fuse.FuseOptions = { - keys: ["name", "slug"], - caseSensitive: false, - minMatchCharLength: 2, - threshold: 0.2, - }; - const fuse = new Fuse(handlers, options); - return fuse.search(filter); + if (filter) { + const options: Fuse.FuseOptions = { + keys: ["name", "slug"], + caseSensitive: false, + minMatchCharLength: 2, + threshold: 0.2, + }; + const fuse = new Fuse(handlers, options); + return fuse.search(filter); + } + return handlers.sort((a, b) => + a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1 + ); } - return handlers.sort((a, b) => - a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1 - ); - }); + ); protected render(): TemplateResult { - const handlers = this._getHandlers(this.handlers, this.filter); + const handlers = this._getHandlers( + this.handlers, + this.filter, + this.hass.localize + ); return html`

${this.hass.localize("ui.panel.config.integrations.new")}

diff --git a/src/layouts/home-assistant.ts b/src/layouts/home-assistant.ts index 97b908001f..c8e0f87f90 100644 --- a/src/layouts/home-assistant.ts +++ b/src/layouts/home-assistant.ts @@ -67,6 +67,12 @@ export class HomeAssistantAppEl extends HassElement { } } + protected hassConnected() { + super.hassConnected(); + // @ts-ignore + this._loadHassTranslations(this.hass!.language, "state"); + } + protected hassReconnected() { super.hassReconnected(); diff --git a/src/onboarding/action-badge.ts b/src/onboarding/action-badge.ts new file mode 100644 index 0000000000..1e70df14ce --- /dev/null +++ b/src/onboarding/action-badge.ts @@ -0,0 +1,89 @@ +import { + css, + CSSResult, + customElement, + html, + LitElement, + property, + TemplateResult, +} from "lit-element"; +import "../components/ha-icon"; + +@customElement("action-badge") +class ActionBadge extends LitElement { + @property() public icon!: string; + + @property() public title!: string; + + @property() public badgeIcon?: string; + + @property({ type: Boolean, reflect: true }) public clickable = false; + + protected render(): TemplateResult { + return html` +
+ + ${this.badgeIcon + ? html` ` + : ""} +
+
${this.title}
+ `; + } + + static get styles(): CSSResult { + return css` + :host { + display: inline-flex; + flex-direction: column; + text-align: center; + color: var(--primary-text-color); + } + + :host([clickable]) { + color: var(--primary-text-color); + } + + .icon { + position: relative; + box-sizing: border-box; + margin: 0 auto 8px; + height: 40px; + width: 40px; + border-radius: 50%; + border: 1px solid var(--secondary-text-color); + display: flex; + align-items: center; + justify-content: center; + } + + :host([clickable]) .icon { + border-color: var(--primary-color); + border-width: 2px; + } + + .badge { + position: absolute; + color: var(--primary-color); + bottom: -5px; + right: -5px; + background-color: white; + border-radius: 50%; + width: 18px; + display: block; + height: 18px; + } + + .title { + min-height: 2.3em; + word-break: break-word; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "action-badge": ActionBadge; + } +} diff --git a/src/onboarding/ha-onboarding.ts b/src/onboarding/ha-onboarding.ts index c11e3a26c7..1bb279b465 100644 --- a/src/onboarding/ha-onboarding.ts +++ b/src/onboarding/ha-onboarding.ts @@ -27,6 +27,7 @@ import { HassElement } from "../state/hass-element"; import { registerServiceWorker } from "../util/register-service-worker"; import "./onboarding-create-user"; import "./onboarding-loading"; +import { HomeAssistant } from "../types"; interface OnboardingEvent { type: T; @@ -45,6 +46,8 @@ declare global { @customElement("ha-onboarding") class HaOnboarding extends litLocalizeLiteMixin(HassElement) { + @property() public hass?: HomeAssistant; + public translationFragment = "page-onboarding"; @property() private _loading = false; @@ -102,6 +105,12 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { if (changedProps.has("language")) { document.querySelector("html")!.setAttribute("lang", this.language!); } + if (changedProps.has("hass")) { + this.hassChanged( + this.hass!, + changedProps.get("hass") as HomeAssistant | undefined + ); + } } private _curStep() { diff --git a/src/onboarding/integration-badge.ts b/src/onboarding/integration-badge.ts index 9588492d08..925440390d 100644 --- a/src/onboarding/integration-badge.ts +++ b/src/onboarding/integration-badge.ts @@ -11,7 +11,7 @@ import "../components/ha-icon"; @customElement("integration-badge") class IntegrationBadge extends LitElement { - @property() public icon!: string; + @property() public domain!: string; @property() public title!: string; @@ -22,7 +22,10 @@ class IntegrationBadge extends LitElement { protected render(): TemplateResult { return html`
- + ${this.badgeIcon ? html` ` : ""} @@ -44,33 +47,35 @@ class IntegrationBadge extends LitElement { color: var(--primary-text-color); } + img { + max-width: 100%; + max-height: 100%; + } + .icon { position: relative; margin: 0 auto 8px; height: 40px; width: 40px; - border-radius: 50%; - border: 1px solid var(--secondary-text-color); display: flex; align-items: center; justify-content: center; } :host([clickable]) .icon { - border-color: var(--primary-color); - border-width: 2px; } .badge { position: absolute; - color: var(--primary-color); - bottom: -5px; - right: -5px; - background-color: white; + color: white; + bottom: -7px; + right: -10px; + background-color: var(--label-badge-green); border-radius: 50%; width: 18px; display: block; height: 18px; + border: 2px solid white; } .title { diff --git a/src/onboarding/onboarding-integrations.ts b/src/onboarding/onboarding-integrations.ts index 74a2d2da65..85ab7b2558 100644 --- a/src/onboarding/onboarding-integrations.ts +++ b/src/onboarding/onboarding-integrations.ts @@ -26,7 +26,9 @@ import { showConfigFlowDialog, } from "../dialogs/config-flow/show-dialog-config-flow"; import { HomeAssistant } from "../types"; +import "./action-badge"; import "./integration-badge"; +import { domainToName } from "../data/integration"; @customElement("onboarding-integrations") class OnboardingIntegrations extends LitElement { @@ -42,8 +44,15 @@ class OnboardingIntegrations extends LitElement { public connectedCallback() { super.connectedCallback(); + this.hass.loadBackendTranslation("title", undefined, true); this._unsubEvents = subscribeConfigFlowInProgress(this.hass, (flows) => { this._discovered = flows; + for (const flow of flows) { + // To render title placeholders + if (flow.context.title_placeholders) { + this.hass.loadBackendTranslation("config", flow.handler); + } + } }); } @@ -62,13 +71,14 @@ class OnboardingIntegrations extends LitElement { // Render discovered and existing entries together sorted by localized title. const entries: Array<[string, TemplateResult]> = this._entries.map( (entry) => { - const title = this.hass.localize(`component.${entry.domain}.title`); + const title = domainToName(this.hass.localize, entry.domain); return [ title, html` `, ]; @@ -83,8 +93,8 @@ class OnboardingIntegrations extends LitElement { `, @@ -102,13 +112,13 @@ class OnboardingIntegrations extends LitElement {
${content}
` From a49c84032b0ebd00d4fcb9a09ad4ed91e055d28d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 22 Apr 2020 01:51:53 -0700 Subject: [PATCH 30/36] Mark titles in config flows optional (#5584) --- src/dialogs/config-flow/show-dialog-config-flow.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dialogs/config-flow/show-dialog-config-flow.ts b/src/dialogs/config-flow/show-dialog-config-flow.ts index 27c4e8706d..46c9657b47 100644 --- a/src/dialogs/config-flow/show-dialog-config-flow.ts +++ b/src/dialogs/config-flow/show-dialog-config-flow.ts @@ -64,8 +64,10 @@ export const showConfigFlowDialog = ( }, renderShowFormStepHeader(hass, step) { - return hass.localize( - `component.${step.handler}.config.step.${step.step_id}.title` + return ( + hass.localize( + `component.${step.handler}.config.step.${step.step_id}.title` + ) || hass.localize(`component.${step.handler}.title`) ); }, From 2b76b3887e205621b6a3a9612867a3ac9fa2f1d8 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 22 Apr 2020 11:12:27 +0200 Subject: [PATCH 31/36] =?UTF-8?q?Add=20device=20automation=20translations?= =?UTF-8?q?=20to=20add=20automation=20device=20dia=E2=80=A6=20(#5573)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add device automation translations to add automation device dialog * Update translations-mixin.ts --- .../devices/device-detail/ha-device-automation-dialog.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/panels/config/devices/device-detail/ha-device-automation-dialog.ts b/src/panels/config/devices/device-detail/ha-device-automation-dialog.ts index 326cf503b8..28a59b03c4 100644 --- a/src/panels/config/devices/device-detail/ha-device-automation-dialog.ts +++ b/src/panels/config/devices/device-detail/ha-device-automation-dialog.ts @@ -39,6 +39,11 @@ export class DialogDeviceAutomation extends LitElement { await this.updateComplete; } + protected firstUpdated(changedProps) { + super.firstUpdated(changedProps); + this.hass.loadBackendTranslation("device_automation"); + } + protected updated(changedProps): void { super.updated(changedProps); From 1c1f9a6a898bb7f38ea4a7905fafa7421f89d60a Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Wed, 22 Apr 2020 05:33:49 -0400 Subject: [PATCH 32/36] Graph Footer: Cache State History (#5499) * Cache State History for entity * State history reset on config change * Fetching * reviews * Merge fixes * Remove file again ? --- .../common/graph/get-history-coordinates.ts | 28 --------- .../header-footer/hui-graph-header-footer.ts | 60 +++++++++++++++++-- 2 files changed, 54 insertions(+), 34 deletions(-) delete mode 100644 src/panels/lovelace/common/graph/get-history-coordinates.ts diff --git a/src/panels/lovelace/common/graph/get-history-coordinates.ts b/src/panels/lovelace/common/graph/get-history-coordinates.ts deleted file mode 100644 index a8d08cf4ca..0000000000 --- a/src/panels/lovelace/common/graph/get-history-coordinates.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { fetchRecent } from "../../../../data/history"; -import { HomeAssistant } from "../../../../types"; -import { coordinates } from "./coordinates"; - -export const getHistoryCoordinates = async ( - hass: HomeAssistant, - entity: string, - hours: number, - detail: number -): Promise => { - const endTime = new Date(); - const startTime = new Date(); - startTime.setHours(endTime.getHours() - hours); - - const stateHistory = await fetchRecent(hass, entity, startTime, endTime); - - if (stateHistory.length < 1 || stateHistory[0].length < 1) { - return []; - } - - const coords = coordinates(stateHistory[0], hours, 500, detail); - - if (!coords) { - return []; - } - - return coords; -}; diff --git a/src/panels/lovelace/header-footer/hui-graph-header-footer.ts b/src/panels/lovelace/header-footer/hui-graph-header-footer.ts index b82616ba61..05f311fd83 100644 --- a/src/panels/lovelace/header-footer/hui-graph-header-footer.ts +++ b/src/panels/lovelace/header-footer/hui-graph-header-footer.ts @@ -9,14 +9,18 @@ import { TemplateResult, } from "lit-element"; import { HomeAssistant } from "../../../types"; -import { getHistoryCoordinates } from "../common/graph/get-history-coordinates"; +import { HassEntity } from "home-assistant-js-websocket"; import "@polymer/paper-spinner/paper-spinner"; import "../components/hui-graph-base"; import { LovelaceHeaderFooter } from "../types"; import { GraphHeaderFooterConfig } from "./types"; +import { hasConfigOrEntityChanged } from "../common/has-changed"; +import { fetchRecent } from "../../../data/history"; +import { coordinates } from "../common/graph/coordinates"; const MINUTE = 60000; +const DAY = 86400000; @customElement("hui-graph-header-footer") export class HuiGraphHeaderFooter extends LitElement @@ -33,6 +37,10 @@ export class HuiGraphHeaderFooter extends LitElement private _date?: Date; + private _stateHistory?: HassEntity[]; + + private _fetching = false; + public setConfig(config: GraphHeaderFooterConfig): void { if (!config?.entity || config.entity.split(".")[0] !== "sensor") { throw new Error( @@ -83,16 +91,25 @@ export class HuiGraphHeaderFooter extends LitElement `; } - protected firstUpdated(): void { - this._date = new Date(); + protected shouldUpdate(changedProps: PropertyValues): boolean { + return hasConfigOrEntityChanged(this, changedProps); } protected updated(changedProps: PropertyValues) { - if (!this._config || !this.hass) { + if ( + !this._config || + !this.hass || + (this._fetching && !changedProps.has("_config")) + ) { return; } if (changedProps.has("_config")) { + const oldConfig = changedProps.get("_config") as GraphHeaderFooterConfig; + if (!oldConfig || oldConfig.entity !== this._config.entity) { + this._stateHistory = []; + } + this._getCoordinates(); } else if (Date.now() - this._date!.getTime() >= MINUTE) { this._getCoordinates(); @@ -100,14 +117,45 @@ export class HuiGraphHeaderFooter extends LitElement } private async _getCoordinates(): Promise { - this._coordinates = await getHistoryCoordinates( + this._fetching = true; + const endTime = new Date(); + const startTime = + !this._date || !this._stateHistory?.length + ? new Date( + new Date().setHours( + endTime.getHours() - this._config!.hours_to_show! + ) + ) + : this._date; + + if (this._stateHistory!.length) { + this._stateHistory = this._stateHistory!.filter( + (entity) => + endTime.getTime() - new Date(entity.last_changed).getTime() <= DAY + ); + } + + const stateHistory = await fetchRecent( this.hass!, this._config!.entity, + startTime, + endTime, + Boolean(this._stateHistory!.length) + ); + + if (stateHistory.length && stateHistory[0].length) { + this._stateHistory!.push(...stateHistory[0]); + } + + this._coordinates = coordinates( + this._stateHistory, this._config!.hours_to_show!, + 500, this._config!.detail! ); - this._date = new Date(); + this._date = endTime; + this._fetching = false; } static get styles(): CSSResult { From 1dfb632fc42b6148bd26b93c542243f79c81f125 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 22 Apr 2020 11:51:50 +0200 Subject: [PATCH 33/36] New layout for integration config (#5580) * WIP * Add filter message to device and entities page * Lokalize * Missed 2 * Fixed in #5581 * Change to hash --- src/components/ha-related-items.ts | 3 +- src/data/config_entries.ts | 15 + src/layouts/hass-tabs-subpage-data-table.ts | 86 ++- src/panels/config/areas/ha-config-areas.ts | 7 - .../devices/ha-config-devices-dashboard.ts | 90 ++- .../config/devices/ha-config-devices.ts | 9 +- .../config/devices/ha-devices-data-table.ts | 273 ------- .../config/entities/ha-config-entities.ts | 150 +++- .../config-entry/ha-ce-entities-card.js | 74 -- .../config-entry/ha-config-entry-page.ts | 213 ------ .../ha-config-entries-dashboard.ts | 402 ---------- .../integrations/ha-config-integrations.ts | 701 +++++++++++++++--- .../lovelace/components/hui-card-options.ts | 2 +- src/resources/markdown_worker.ts | 1 + src/resources/styles.ts | 26 +- src/translations/en.json | 20 +- 16 files changed, 964 insertions(+), 1108 deletions(-) delete mode 100644 src/panels/config/devices/ha-devices-data-table.ts delete mode 100644 src/panels/config/integrations/config-entry/ha-ce-entities-card.js delete mode 100755 src/panels/config/integrations/config-entry/ha-config-entry-page.ts delete mode 100644 src/panels/config/integrations/ha-config-entries-dashboard.ts diff --git a/src/components/ha-related-items.ts b/src/components/ha-related-items.ts index 6077f0c284..3a4e59a3ea 100644 --- a/src/components/ha-related-items.ts +++ b/src/components/ha-related-items.ts @@ -1,3 +1,4 @@ +/* eslint-disable lit/no-invalid-html */ import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, @@ -95,7 +96,7 @@ export class HaRelatedItems extends SubscribeMixin(LitElement) { )}: ${this.hass.localize(`component.${entry.domain}.title`)}: diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts index 9d5388c5bf..527838ff3b 100644 --- a/src/data/config_entries.ts +++ b/src/data/config_entries.ts @@ -10,6 +10,10 @@ export interface ConfigEntry { supports_options: boolean; } +export interface ConfigEntryMutableParams { + title: string; +} + export interface ConfigEntrySystemOptions { disable_new_entities: boolean; } @@ -17,6 +21,17 @@ export interface ConfigEntrySystemOptions { export const getConfigEntries = (hass: HomeAssistant) => hass.callApi("GET", "config/config_entries/entry"); +export const updateConfigEntry = ( + hass: HomeAssistant, + configEntryId: string, + updatedValues: Partial +) => + hass.callWS({ + type: "config_entries/update", + entry_id: configEntryId, + ...updatedValues, + }); + export const deleteConfigEntry = (hass: HomeAssistant, configEntryId: string) => hass.callApi<{ require_restart: boolean; diff --git a/src/layouts/hass-tabs-subpage-data-table.ts b/src/layouts/hass-tabs-subpage-data-table.ts index d761ec0e6c..add5bc19d3 100644 --- a/src/layouts/hass-tabs-subpage-data-table.ts +++ b/src/layouts/hass-tabs-subpage-data-table.ts @@ -17,6 +17,9 @@ import type { import type { HomeAssistant, Route } from "../types"; import "./hass-tabs-subpage"; import type { PageNavigation } from "./hass-tabs-subpage"; +import "@material/mwc-button/mwc-button"; +import { navigate } from "../common/navigate"; +import "@polymer/paper-tooltip/paper-tooltip"; @customElement("hass-tabs-subpage-data-table") export class HaTabsSubpageDataTable extends LitElement { @@ -62,6 +65,12 @@ export class HaTabsSubpageDataTable extends LitElement { */ @property({ type: String }) public filter = ""; + /** + * List of strings that show what the data is currently filtered by. + * @type {Array} + */ + @property({ type: Array }) public activeFilters?; + /** * What path to use when the back button is pressed. * @type {String} @@ -118,6 +127,24 @@ export class HaTabsSubpageDataTable extends LitElement { no-underline @value-changed=${this._handleSearchChange} > + ${this.activeFilters + ? html`
+
+ + + ${this.hass.localize( + "ui.panel.config.filtering.filtering_by" + )} + ${this.activeFilters.join(", ")} + +
+ ${this.hass.localize( + "ui.panel.config.filtering.clear" + )} +
` + : ""}
@@ -143,8 +170,24 @@ export class HaTabsSubpageDataTable extends LitElement { no-label-float no-underline @value-changed=${this._handleSearchChange} - >
+ > + + ${this.activeFilters + ? html`
+ ${this.hass.localize( + "ui.panel.config.filtering.filtering_by" + )} + ${this.activeFilters.join(", ")} + ${this.hass.localize( + "ui.panel.config.filtering.clear" + )} +
` + : ""} +
` : html`
`} @@ -157,6 +200,10 @@ export class HaTabsSubpageDataTable extends LitElement { this.filter = ev.detail.value; } + private _clearFilter() { + navigate(this, window.location.pathname); + } + static get styles(): CSSResult { return css` ha-data-table { @@ -171,19 +218,54 @@ export class HaTabsSubpageDataTable extends LitElement { .table-header { border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12); padding: 0 16px; + display: flex; + align-items: center; } .search-toolbar { + display: flex; + align-items: center; color: var(--secondary-text-color); padding: 0 16px; } search-input { position: relative; top: 2px; + flex-grow: 1; } search-input.header { left: -8px; top: -7px; } + .active-filters { + color: var(--primary-text-color); + position: relative; + display: flex; + align-items: center; + padding: 2px 2px 2px 8px; + margin-left: 4px; + font-size: 14px; + } + .active-filters ha-icon { + color: var(--primary-color); + } + .active-filters mwc-button { + margin-left: 8px; + } + .active-filters::before { + background-color: var(--primary-color); + opacity: 0.12; + border-radius: 4px; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + content: ""; + } + .search-toolbar .active-filters { + top: -8px; + right: -16px; + } `; } } diff --git a/src/panels/config/areas/ha-config-areas.ts b/src/panels/config/areas/ha-config-areas.ts index 2e1fbcaa09..3e4bf1c0f4 100644 --- a/src/panels/config/areas/ha-config-areas.ts +++ b/src/panels/config/areas/ha-config-areas.ts @@ -68,13 +68,6 @@ class HaConfigAreas extends HassRouterPage { } } - protected firstUpdated(changedProps) { - super.firstUpdated(changedProps); - this.addEventListener("hass-reload-entries", () => { - this._loadData(); - }); - } - protected updated(changedProps: PropertyValues) { super.updated(changedProps); if (!this._unsubs && changedProps.has("hass")) { diff --git a/src/panels/config/devices/ha-config-devices-dashboard.ts b/src/panels/config/devices/ha-config-devices-dashboard.ts index a89a036a77..a14c7c3d13 100644 --- a/src/panels/config/devices/ha-config-devices-dashboard.ts +++ b/src/panels/config/devices/ha-config-devices-dashboard.ts @@ -26,9 +26,17 @@ import { findBatteryEntity, } from "../../../data/entity_registry"; import "../../../layouts/hass-tabs-subpage-data-table"; +import "../../../components/entity/ha-state-icon"; import { HomeAssistant, Route } from "../../../types"; import { configSections } from "../ha-panel-config"; -import { DeviceRowData } from "./ha-devices-data-table"; +import { domainToName } from "../../../data/integration"; + +interface DeviceRowData extends DeviceRegistryEntry { + device?: DeviceRowData; + area?: string; + integration?: string; + battery_entity?: string; +} @customElement("ha-config-devices-dashboard") export class HaConfigDeviceDashboard extends LitElement { @@ -46,17 +54,53 @@ export class HaConfigDeviceDashboard extends LitElement { @property() public areas!: AreaRegistryEntry[]; - @property() public domain!: string; - @property() public route!: Route; + @property() private _searchParms = new URLSearchParams( + window.location.search + ); + + private _activeFilters = memoizeOne( + ( + entries: ConfigEntry[], + filters: URLSearchParams, + localize: LocalizeFunc + ): string[] | undefined => { + const filterTexts: string[] = []; + filters.forEach((value, key) => { + switch (key) { + case "config_entry": { + const configEntry = entries.find( + (entry) => entry.entry_id === value + ); + if (!configEntry) { + break; + } + const integrationName = domainToName(localize, configEntry.domain); + filterTexts.push( + `${this.hass.localize( + "ui.panel.config.integrations.integration" + )} ${integrationName}${ + integrationName !== configEntry.title + ? `: ${configEntry.title}` + : "" + }` + ); + break; + } + } + }); + return filterTexts.length ? filterTexts : undefined; + } + ); + private _devices = memoizeOne( ( devices: DeviceRegistryEntry[], entries: ConfigEntry[], entities: EntityRegistryEntry[], areas: AreaRegistryEntry[], - domain: string, + filters: URLSearchParams, localize: LocalizeFunc ) => { // Some older installations might have devices pointing at invalid entryIDs @@ -90,14 +134,15 @@ export class HaConfigDeviceDashboard extends LitElement { areaLookup[area.area_id] = area; } - if (domain) { - outputDevices = outputDevices.filter((device) => - device.config_entries.find( - (entryId) => - entryId in entryLookup && entryLookup[entryId].domain === domain - ) - ); - } + filters.forEach((value, key) => { + switch (key) { + case "config_entry": + outputDevices = outputDevices.filter((device) => + device.config_entries.includes(value) + ); + break; + } + }); outputDevices = outputDevices.map((device) => { return { @@ -238,12 +283,24 @@ export class HaConfigDeviceDashboard extends LitElement { } ); + public constructor() { + super(); + window.addEventListener("location-changed", () => { + this._searchParms = new URLSearchParams(window.location.search); + }); + window.addEventListener("popstate", () => { + this._searchParms = new URLSearchParams(window.location.search); + }); + } + protected render(): TemplateResult { return html` { - this._configEntries = configEntries.sort((conf1, conf2) => - compare(conf1.title, conf2.title) - ); + this._configEntries = configEntries; }); if (this._unsubs) { return; diff --git a/src/panels/config/devices/ha-devices-data-table.ts b/src/panels/config/devices/ha-devices-data-table.ts deleted file mode 100644 index cbe8cd7e69..0000000000 --- a/src/panels/config/devices/ha-devices-data-table.ts +++ /dev/null @@ -1,273 +0,0 @@ -import { - customElement, - html, - LitElement, - property, - TemplateResult, -} from "lit-element"; -import memoizeOne from "memoize-one"; -import { navigate } from "../../../common/navigate"; -import { LocalizeFunc } from "../../../common/translations/localize"; -import "../../../components/data-table/ha-data-table"; -import type { - DataTableColumnContainer, - DataTableRowData, - RowClickedEvent, -} from "../../../components/data-table/ha-data-table"; -import "../../../components/entity/ha-state-icon"; -import type { AreaRegistryEntry } from "../../../data/area_registry"; -import type { ConfigEntry } from "../../../data/config_entries"; -import { - computeDeviceName, - DeviceEntityLookup, - DeviceRegistryEntry, -} from "../../../data/device_registry"; -import { - EntityRegistryEntry, - findBatteryEntity, -} from "../../../data/entity_registry"; -import type { HomeAssistant } from "../../../types"; - -export interface DeviceRowData extends DeviceRegistryEntry { - device?: DeviceRowData; - area?: string; - integration?: string; - battery_entity?: string; -} - -@customElement("ha-devices-data-table") -export class HaDevicesDataTable extends LitElement { - @property() public hass!: HomeAssistant; - - @property() public narrow = false; - - @property() public devices!: DeviceRegistryEntry[]; - - @property() public entries!: ConfigEntry[]; - - @property() public entities!: EntityRegistryEntry[]; - - @property() public areas!: AreaRegistryEntry[]; - - @property() public domain!: string; - - private _devices = memoizeOne( - ( - devices: DeviceRegistryEntry[], - entries: ConfigEntry[], - entities: EntityRegistryEntry[], - areas: AreaRegistryEntry[], - domain: string, - localize: LocalizeFunc - ) => { - // Some older installations might have devices pointing at invalid entryIDs - // So we guard for that. - - let outputDevices: DeviceRowData[] = devices; - - const deviceLookup: { [deviceId: string]: DeviceRegistryEntry } = {}; - for (const device of devices) { - deviceLookup[device.id] = device; - } - - const deviceEntityLookup: DeviceEntityLookup = {}; - for (const entity of entities) { - if (!entity.device_id) { - continue; - } - if (!(entity.device_id in deviceEntityLookup)) { - deviceEntityLookup[entity.device_id] = []; - } - deviceEntityLookup[entity.device_id].push(entity); - } - - const entryLookup: { [entryId: string]: ConfigEntry } = {}; - for (const entry of entries) { - entryLookup[entry.entry_id] = entry; - } - - const areaLookup: { [areaId: string]: AreaRegistryEntry } = {}; - for (const area of areas) { - areaLookup[area.area_id] = area; - } - - if (domain) { - outputDevices = outputDevices.filter((device) => - device.config_entries.find( - (entryId) => - entryId in entryLookup && entryLookup[entryId].domain === domain - ) - ); - } - - outputDevices = outputDevices.map((device) => { - return { - ...device, - name: computeDeviceName( - device, - this.hass, - deviceEntityLookup[device.id] - ), - model: device.model || "", - manufacturer: device.manufacturer || "", - area: device.area_id ? areaLookup[device.area_id].name : "No area", - integration: device.config_entries.length - ? device.config_entries - .filter((entId) => entId in entryLookup) - .map( - (entId) => - localize(`component.${entryLookup[entId].domain}.title`) || - entryLookup[entId].domain - ) - .join(", ") - : "No integration", - battery_entity: this._batteryEntity(device.id, deviceEntityLookup), - }; - }); - - return outputDevices; - } - ); - - private _columns = memoizeOne( - (narrow: boolean): DataTableColumnContainer => - narrow - ? { - name: { - title: "Device", - sortable: true, - filterable: true, - direction: "asc", - grows: true, - template: (name, device: DataTableRowData) => { - const battery = device.battery_entity - ? this.hass.states[device.battery_entity] - : undefined; - // Have to work on a nice layout for mobile - return html` - ${name}
- ${device.area} | ${device.integration}
- ${battery && !isNaN(battery.state as any) - ? html` - ${battery.state}% - - ` - : ""} - `; - }, - }, - } - : { - name: { - title: this.hass.localize( - "ui.panel.config.devices.data_table.device" - ), - sortable: true, - filterable: true, - direction: "asc", - grows: true, - }, - manufacturer: { - title: this.hass.localize( - "ui.panel.config.devices.data_table.manufacturer" - ), - sortable: true, - filterable: true, - width: "15%", - }, - model: { - title: this.hass.localize( - "ui.panel.config.devices.data_table.model" - ), - sortable: true, - filterable: true, - width: "15%", - }, - area: { - title: this.hass.localize( - "ui.panel.config.devices.data_table.area" - ), - sortable: true, - filterable: true, - width: "15%", - }, - integration: { - title: this.hass.localize( - "ui.panel.config.devices.data_table.integration" - ), - sortable: true, - filterable: true, - width: "15%", - }, - battery_entity: { - title: this.hass.localize( - "ui.panel.config.devices.data_table.battery" - ), - sortable: true, - type: "numeric", - width: "15%", - maxWidth: "90px", - template: (batteryEntity: string) => { - const battery = batteryEntity - ? this.hass.states[batteryEntity] - : undefined; - return battery && !isNaN(battery.state as any) - ? html` - ${battery.state}% - - ` - : html` - `; - }, - }, - } - ); - - protected render(): TemplateResult { - return html` - - `; - } - - private _batteryEntity( - deviceId: string, - deviceEntityLookup: DeviceEntityLookup - ): string | undefined { - const batteryEntity = findBatteryEntity( - this.hass, - deviceEntityLookup[deviceId] || [] - ); - return batteryEntity ? batteryEntity.entity_id : undefined; - } - - private _handleRowClicked(ev: CustomEvent) { - const deviceId = (ev.detail as RowClickedEvent).id; - navigate(this, `/config/devices/device/${deviceId}`); - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-devices-data-table": HaDevicesDataTable; - } -} diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index 75fcdfe1f6..3ccdf57475 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -49,6 +49,10 @@ import { loadEntityEditorDialog, showEntityEditorDialog, } from "./show-dialog-entity-editor"; +import { getConfigEntries, ConfigEntry } from "../../../data/config_entries"; +import { LocalizeFunc } from "../../../common/translations/localize"; +import { domainToName } from "../../../data/integration"; +import { navigate } from "../../../common/navigate"; export interface StateEntity extends EntityRegistryEntry { readonly?: boolean; @@ -76,6 +80,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { @property() private _stateEntities: StateEntity[] = []; + @property() public _entries?: ConfigEntry[]; + @property() private _showDisabled = false; @property() private _showUnavailable = true; @@ -84,6 +90,10 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { @property() private _filter = ""; + @property() private _searchParms = new URLSearchParams( + window.location.search + ); + @property() private _selectedEntities: string[] = []; @query("hass-tabs-subpage-data-table") @@ -91,6 +101,44 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { private getDialog?: () => DialogEntityEditor | undefined; + private _activeFilters = memoize( + ( + filters: URLSearchParams, + localize: LocalizeFunc, + entries?: ConfigEntry[] + ): string[] | undefined => { + const filterTexts: string[] = []; + filters.forEach((value, key) => { + switch (key) { + case "config_entry": { + if (!entries) { + this._loadConfigEntries(); + break; + } + const configEntry = entries.find( + (entry) => entry.entry_id === value + ); + if (!configEntry) { + break; + } + const integrationName = domainToName(localize, configEntry.domain); + filterTexts.push( + `${this.hass.localize( + "ui.panel.config.integrations.integration" + )} ${integrationName}${ + integrationName !== configEntry.title + ? `: ${configEntry.title}` + : "" + }` + ); + break; + } + } + }); + return filterTexts.length ? filterTexts : undefined; + } + ); + private _columns = memoize( (narrow, _language): DataTableColumnContainer => { const columns: DataTableColumnContainer = { @@ -202,6 +250,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { ( entities: EntityRegistryEntry[], stateEntities: StateEntity[], + filters: URLSearchParams, showDisabled: boolean, showUnavailable: boolean, showReadOnly: boolean @@ -212,9 +261,19 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { const result: EntityRow[] = []; - for (const entry of showReadOnly - ? entities.concat(stateEntities) - : entities) { + entities = showReadOnly ? entities.concat(stateEntities) : entities; + + filters.forEach((value, key) => { + switch (key) { + case "config_entry": + entities = entities.filter( + (entity) => entity.config_entry_id === value + ); + break; + } + }); + + for (const entry of entities) { const entity = this.hass.states[entry.entity_id]; const unavailable = entity?.state === "unavailable"; const restored = entity?.attributes.restored; @@ -253,6 +312,16 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { } ); + public constructor() { + super(); + window.addEventListener("location-changed", () => { + this._searchParms = new URLSearchParams(window.location.search); + }); + window.addEventListener("popstate", () => { + this._searchParms = new URLSearchParams(window.location.search); + }); + } + public hassSubscribe(): UnsubscribeFunc[] { return [ subscribeEntityRegistry(this.hass.connection!, (entities) => { @@ -277,6 +346,11 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { if (!this.hass || this._entities === undefined) { return html` `; } + const activeFilters = this._activeFilters( + this._searchParms, + this.hass.localize, + this._entries + ); const headerToolbar = this._selectedEntities.length ? html`

@@ -345,7 +419,29 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { no-underline @value-changed=${this._handleSearchChange} .filter=${this._filter} - > + >${activeFilters + ? html`

+ ${this.narrow + ? html`
+ + + ${this.hass.localize( + "ui.panel.config.filtering.filtering_by" + )} + ${activeFilters.join(", ")} + +
` + : `${this.hass.localize( + "ui.panel.config.filtering.filtering_by" + )} ${activeFilters.join(", ")}`} + ${this.hass.localize( + "ui.panel.config.filtering.clear" + )} +
` + : ""} paper-icon-button { margin: 8px; } + .active-filters { + color: var(--primary-text-color); + position: relative; + display: flex; + align-items: center; + padding: 2px 2px 2px 8px; + margin-left: 4px; + font-size: 14px; + } + .active-filters ha-icon { + color: var(--primary-color); + } + .active-filters mwc-button { + margin-left: 8px; + } + .active-filters::before { + background-color: var(--primary-color); + opacity: 0.12; + border-radius: 4px; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + content: ""; + } `; } } diff --git a/src/panels/config/integrations/config-entry/ha-ce-entities-card.js b/src/panels/config/integrations/config-entry/ha-ce-entities-card.js deleted file mode 100644 index 343c801bf1..0000000000 --- a/src/panels/config/integrations/config-entry/ha-ce-entities-card.js +++ /dev/null @@ -1,74 +0,0 @@ -import "@polymer/paper-item/paper-icon-item"; -import "@polymer/paper-item/paper-item-body"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import "../../../../components/entity/state-badge"; -import "../../../../components/ha-card"; -import { computeEntityRegistryName } from "../../../../data/entity_registry"; -import "../../../../layouts/hass-subpage"; -import { EventsMixin } from "../../../../mixins/events-mixin"; -import LocalizeMixIn from "../../../../mixins/localize-mixin"; - -/* - * @appliesMixin LocalizeMixIn - * @appliesMixin EventsMixin - */ -class HaCeEntitiesCard extends LocalizeMixIn(EventsMixin(PolymerElement)) { - static get template() { - return html` - - - - - `; - } - - static get properties() { - return { - heading: String, - entities: Array, - hass: Object, - }; - } - - _computeStateObj(entity, hass) { - return hass.states[entity.entity_id]; - } - - _computeEntityName(entity, hass) { - return ( - computeEntityRegistryName(hass, entity) || - `(${this.localize( - "ui.panel.config.integrations.config_entry.entity_unavailable" - )})` - ); - } - - _openMoreInfo(ev) { - this.fire("hass-more-info", { entityId: ev.model.entity.entity_id }); - } -} - -customElements.define("ha-ce-entities-card", HaCeEntitiesCard); diff --git a/src/panels/config/integrations/config-entry/ha-config-entry-page.ts b/src/panels/config/integrations/config-entry/ha-config-entry-page.ts deleted file mode 100755 index d02eaa66a3..0000000000 --- a/src/panels/config/integrations/config-entry/ha-config-entry-page.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { css, CSSResult, html, LitElement, property } from "lit-element"; -import memoizeOne from "memoize-one"; -import { fireEvent } from "../../../../common/dom/fire_event"; -import { navigate } from "../../../../common/navigate"; -import { AreaRegistryEntry } from "../../../../data/area_registry"; -import { - ConfigEntry, - deleteConfigEntry, -} from "../../../../data/config_entries"; -import { DeviceRegistryEntry } from "../../../../data/device_registry"; -import { EntityRegistryEntry } from "../../../../data/entity_registry"; -import { showConfigEntrySystemOptionsDialog } from "../../../../dialogs/config-entry-system-options/show-dialog-config-entry-system-options"; -import { showOptionsFlowDialog } from "../../../../dialogs/config-flow/show-dialog-options-flow"; -import { - showAlertDialog, - showConfirmationDialog, -} from "../../../../dialogs/generic/show-dialog-box"; -import "../../../../layouts/hass-error-screen"; -import "../../../../layouts/hass-subpage"; -import { HomeAssistant } from "../../../../types"; -import "../../devices/ha-devices-data-table"; -import "./ha-ce-entities-card"; - -class HaConfigEntryPage extends LitElement { - @property() public hass!: HomeAssistant; - - @property() public narrow!: boolean; - - @property() public configEntryId!: string; - - @property() public configEntries!: ConfigEntry[]; - - @property() public entityRegistryEntries!: EntityRegistryEntry[]; - - @property() public deviceRegistryEntries!: DeviceRegistryEntry[]; - - @property() public areas!: AreaRegistryEntry[]; - - private get _configEntry(): ConfigEntry | undefined { - return this.configEntries - ? this.configEntries.find( - (entry) => entry.entry_id === this.configEntryId - ) - : undefined; - } - - private _computeConfigEntryDevices = memoizeOne( - (configEntry: ConfigEntry, devices: DeviceRegistryEntry[]) => { - if (!devices) { - return []; - } - return devices.filter((device) => - device.config_entries.includes(configEntry.entry_id) - ); - } - ); - - private _computeNoDeviceEntities = memoizeOne( - (configEntry: ConfigEntry, entities: EntityRegistryEntry[]) => { - if (!entities) { - return []; - } - return entities.filter( - (ent) => !ent.device_id && ent.config_entry_id === configEntry.entry_id - ); - } - ); - - protected render() { - const configEntry = this._configEntry; - - if (!configEntry) { - return html` - - `; - } - - const configEntryDevices = this._computeConfigEntryDevices( - configEntry, - this.deviceRegistryEntries - ); - - const noDeviceEntities = this._computeNoDeviceEntities( - configEntry, - this.entityRegistryEntries - ); - - return html` - - ${configEntry.supports_options - ? html` - - ` - : ""} - - - -
- ${configEntryDevices.length === 0 && noDeviceEntities.length === 0 - ? html` -

- ${this.hass.localize( - "ui.panel.config.integrations.config_entry.no_devices" - )} -

- ` - : html` - - `} - ${noDeviceEntities.length > 0 - ? html` - - ` - : ""} -
-
- `; - } - - private _showSettings() { - showOptionsFlowDialog(this, this._configEntry!); - } - - private _showSystemOptions() { - showConfigEntrySystemOptionsDialog(this, { - entry: this._configEntry!, - }); - } - - private _confirmRemoveEntry() { - showConfirmationDialog(this, { - text: this.hass.localize( - "ui.panel.config.integrations.config_entry.delete_confirm" - ), - confirm: () => this._removeEntry(), - }); - } - - private _removeEntry() { - deleteConfigEntry(this.hass, this.configEntryId).then((result) => { - fireEvent(this, "hass-reload-entries"); - if (result.require_restart) { - showAlertDialog(this, { - text: this.hass.localize( - "ui.panel.config.integrations.config_entry.restart_confirm" - ), - }); - } - navigate(this, "/config/integrations/dashboard", true); - }); - } - - static get styles(): CSSResult { - return css` - .content { - padding: 4px; - } - p { - text-align: center; - } - ha-devices-data-table { - width: 100%; - } - `; - } -} - -customElements.define("ha-config-entry-page", HaConfigEntryPage); diff --git a/src/panels/config/integrations/ha-config-entries-dashboard.ts b/src/panels/config/integrations/ha-config-entries-dashboard.ts deleted file mode 100644 index 2fac604f49..0000000000 --- a/src/panels/config/integrations/ha-config-entries-dashboard.ts +++ /dev/null @@ -1,402 +0,0 @@ -import "@material/mwc-button"; -import "@polymer/iron-flex-layout/iron-flex-layout-classes"; -import "@polymer/iron-icon/iron-icon"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-item/paper-item-body"; -import "@polymer/paper-listbox/paper-listbox"; -import "@polymer/paper-tooltip/paper-tooltip"; -import { HassEntity } from "home-assistant-js-websocket"; -import { - css, - CSSResult, - customElement, - html, - LitElement, - property, - TemplateResult, -} from "lit-element"; -import { fireEvent } from "../../../common/dom/fire_event"; -import { computeStateName } from "../../../common/entity/compute_state_name"; -import { computeRTL } from "../../../common/util/compute_rtl"; -import "../../../components/entity/ha-state-icon"; -import "../../../components/ha-card"; -import "../../../components/ha-fab"; -import "../../../components/ha-icon"; -import "../../../components/ha-icon-next"; -import { ConfigEntry, deleteConfigEntry } from "../../../data/config_entries"; -import { - DISCOVERY_SOURCES, - ignoreConfigFlow, - localizeConfigFlowTitle, -} from "../../../data/config_flow"; -import { DataEntryFlowProgress } from "../../../data/data_entry_flow"; -import { EntityRegistryEntry } from "../../../data/entity_registry"; -import { - loadConfigFlowDialog, - showConfigFlowDialog, -} from "../../../dialogs/config-flow/show-dialog-config-flow"; -import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; -import "../../../layouts/hass-tabs-subpage"; -import "../../../resources/ha-style"; -import { HomeAssistant, Route } from "../../../types"; -import "../ha-config-section"; -import { configSections } from "../ha-panel-config"; - -@customElement("ha-config-entries-dashboard") -export class HaConfigManagerDashboard extends LitElement { - @property() public hass!: HomeAssistant; - - @property() public showAdvanced!: boolean; - - @property() public isWide!: boolean; - - @property() public narrow!: boolean; - - @property() public route!: Route; - - @property() private configEntries!: ConfigEntry[]; - - /** - * Entity Registry entries. - */ - @property() private entityRegistryEntries!: EntityRegistryEntry[]; - - /** - * Current flows that are in progress and have not been started by a user. - * For example, can be discovered devices that require more config. - */ - @property() private configEntriesInProgress!: DataEntryFlowProgress[]; - - @property() private _showIgnored = false; - - public connectedCallback() { - super.connectedCallback(); - loadConfigFlowDialog(); - } - - protected render(): TemplateResult { - return html` - - - - - - ${this.hass.localize( - this._showIgnored - ? "ui.panel.config.integrations.ignore.hide_ignored" - : "ui.panel.config.integrations.ignore.show_ignored" - )} - - - - - ${this._showIgnored - ? html` - - ${this.hass.localize( - "ui.panel.config.integrations.ignore.ignored" - )} - - ${this.configEntries - .filter((item) => item.source === "ignore") - .map( - (item: ConfigEntry) => html` - - - ${this.hass.localize( - `component.${item.domain}.title` - )} - - - - ` - )} - - - ` - : ""} - ${this.configEntriesInProgress.length - ? html` - - ${this.hass.localize( - "ui.panel.config.integrations.discovered" - )} - - ${this.configEntriesInProgress.map( - (flow) => html` -
- - ${localizeConfigFlowTitle(this.hass.localize, flow)} - - ${DISCOVERY_SOURCES.includes(flow.context.source) && - flow.context.unique_id - ? html` - - ${this.hass.localize( - "ui.panel.config.integrations.ignore.ignore" - )} - - ` - : ""} - ${this.hass.localize( - "ui.panel.config.integrations.configure" - )} -
- ` - )} -
-
- ` - : ""} - - - - ${this.hass.localize("ui.panel.config.integrations.configured")} - - - ${this.entityRegistryEntries.length - ? this.configEntries.map((item: any, idx) => - item.source === "ignore" - ? "" - : html` -
- - - -
- ${this.hass.localize( - `component.${item.domain}.title` - )}: - ${item.title} -
-
- ${this._getEntities(item).map( - (entity) => html` - - - ${computeStateName( - entity - )} - - ` - )} -
-
- -
-
- ` - ) - : html` -
- -
- ${this.hass.localize( - "ui.panel.config.integrations.none" - )} -
-
-
- `} - - - - - - `; - } - - private _createFlow() { - showConfigFlowDialog(this, { - dialogClosedCallback: () => fireEvent(this, "hass-reload-entries"), - showAdvanced: this.showAdvanced, - }); - } - - private _continueFlow(ev: Event) { - showConfigFlowDialog(this, { - continueFlowId: (ev.target! as any).flowId, - dialogClosedCallback: () => fireEvent(this, "hass-reload-entries"), - }); - } - - private _ignoreFlow(ev: Event) { - const flow = (ev.target! as any).flow; - showConfirmationDialog(this, { - title: this.hass!.localize( - "ui.panel.config.integrations.ignore.confirm_ignore_title", - "name", - localizeConfigFlowTitle(this.hass.localize, flow) - ), - text: this.hass!.localize( - "ui.panel.config.integrations.ignore.confirm_ignore" - ), - confirmText: this.hass!.localize( - "ui.panel.config.integrations.ignore.ignore" - ), - confirm: () => { - ignoreConfigFlow(this.hass, flow.flow_id); - fireEvent(this, "hass-reload-entries"); - }, - }); - } - - private _toggleShowIgnored() { - this._showIgnored = !this._showIgnored; - } - - private async _removeIgnoredIntegration(ev: Event) { - const entry = (ev.target! as any).entry; - showConfirmationDialog(this, { - title: this.hass!.localize( - "ui.panel.config.integrations.ignore.confirm_delete_ignore_title", - "name", - this.hass.localize(`component.${entry.domain}.title`) - ), - text: this.hass!.localize( - "ui.panel.config.integrations.ignore.confirm_delete_ignore" - ), - confirmText: this.hass!.localize( - "ui.panel.config.integrations.ignore.stop_ignore" - ), - confirm: async () => { - const result = await deleteConfigEntry(this.hass, entry.entry_id); - if (result.require_restart) { - alert( - this.hass.localize( - "ui.panel.config.integrations.config_entry.restart_confirm" - ) - ); - } - fireEvent(this, "hass-reload-entries"); - }, - }); - } - - private _getEntities(configEntry: ConfigEntry): HassEntity[] { - if (!this.entityRegistryEntries) { - return []; - } - const states: HassEntity[] = []; - this.entityRegistryEntries.forEach((entity) => { - if ( - entity.config_entry_id === configEntry.entry_id && - entity.entity_id in this.hass.states - ) { - states.push(this.hass.states[entity.entity_id]); - } - }); - return states; - } - - private _onImageLoad(ev) { - ev.target.style.visibility = "initial"; - } - - private _onImageError(ev) { - ev.target.style.visibility = "hidden"; - } - - static get styles(): CSSResult { - return css` - mwc-button { - align-self: center; - } - .config-entry-row { - display: flex; - padding: 0 16px; - } - ha-icon { - cursor: pointer; - margin: 8px; - } - .configured { - padding-bottom: 24px; - } - .configured a { - color: var(--primary-text-color); - text-decoration: none; - } - ha-fab { - position: fixed; - bottom: 16px; - right: 16px; - z-index: 1; - } - ha-fab[narrow] { - bottom: 84px; - } - ha-fab[rtl] { - right: auto; - left: 16px; - } - .overflow { - width: 56px; - } - img { - width: 50px; - margin-right: 16px; - } - `; - } -} diff --git a/src/panels/config/integrations/ha-config-integrations.ts b/src/panels/config/integrations/ha-config-integrations.ts index abf79ff220..09aa9847e4 100644 --- a/src/panels/config/integrations/ha-config-integrations.ts +++ b/src/panels/config/integrations/ha-config-integrations.ts @@ -1,14 +1,32 @@ +/* eslint-disable lit/no-invalid-html */ import "@polymer/app-route/app-route"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; -import { customElement, property, PropertyValues } from "lit-element"; +import { + customElement, + property, + PropertyValues, + LitElement, + TemplateResult, + html, + CSSResult, + css, +} from "lit-element"; import { compare } from "../../../common/string/compare"; +import { computeRTL } from "../../../common/util/compute_rtl"; +import "../../../components/entity/ha-state-icon"; +import "../../../components/ha-card"; +import "../../../components/ha-fab"; import { - AreaRegistryEntry, - subscribeAreaRegistry, -} from "../../../data/area_registry"; -import { ConfigEntry, getConfigEntries } from "../../../data/config_entries"; + ConfigEntry, + deleteConfigEntry, + getConfigEntries, + updateConfigEntry, +} from "../../../data/config_entries"; import { + DISCOVERY_SOURCES, getConfigFlowInProgressCollection, + ignoreConfigFlow, + localizeConfigFlowTitle, subscribeConfigFlowInProgress, } from "../../../data/config_flow"; import { DataEntryFlowProgress } from "../../../data/data_entry_flow"; @@ -20,22 +38,24 @@ import { EntityRegistryEntry, subscribeEntityRegistry, } from "../../../data/entity_registry"; +import { showConfigEntrySystemOptionsDialog } from "../../../dialogs/config-entry-system-options/show-dialog-config-entry-system-options"; +import { showConfigFlowDialog } from "../../../dialogs/config-flow/show-dialog-config-flow"; +import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-options-flow"; import { - HassRouterPage, - RouterOptions, -} from "../../../layouts/hass-router-page"; -import { HomeAssistant } from "../../../types"; -import "./config-entry/ha-config-entry-page"; -import "./ha-config-entries-dashboard"; - -declare global { - interface HASSDomEvents { - "hass-reload-entries": undefined; - } -} + showAlertDialog, + showConfirmationDialog, + showPromptDialog, +} from "../../../dialogs/generic/show-dialog-box"; +import "../../../layouts/hass-tabs-subpage"; +import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; +import { HomeAssistant, Route } from "../../../types"; +import { configSections } from "../ha-panel-config"; +import { domainToName } from "../../../data/integration"; +import { haStyle } from "../../../resources/styles"; +import { afterNextRender } from "../../../common/util/render-status"; @customElement("ha-config-integrations") -class HaConfigIntegrations extends HassRouterPage { +class HaConfigIntegrations extends SubscribeMixin(LitElement) { @property() public hass!: HomeAssistant; @property() public narrow!: boolean; @@ -44,17 +64,7 @@ class HaConfigIntegrations extends HassRouterPage { @property() public showAdvanced!: boolean; - protected routerOptions: RouterOptions = { - defaultPage: "dashboard", - routes: { - dashboard: { - tag: "ha-config-entries-dashboard", - }, - config_entry: { - tag: "ha-config-entry-page", - }, - }, - }; + @property() public route!: Route; @property() private _configEntries: ConfigEntry[] = []; @@ -64,78 +74,14 @@ class HaConfigIntegrations extends HassRouterPage { @property() private _deviceRegistryEntries: DeviceRegistryEntry[] = []; - @property() private _areas: AreaRegistryEntry[] = []; + @property() private _showIgnored = false; - private _unsubs?: UnsubscribeFunc[]; + @property() private _searchParms = new URLSearchParams( + window.location.hash.substring(1) + ); - public connectedCallback() { - super.connectedCallback(); - - if (!this.hass) { - return; - } - this._loadData(); - } - - public disconnectedCallback() { - super.disconnectedCallback(); - if (this._unsubs) { - while (this._unsubs.length) { - this._unsubs.pop()!(); - } - this._unsubs = undefined; - } - } - - protected firstUpdated(changedProps) { - super.firstUpdated(changedProps); - this.addEventListener("hass-reload-entries", () => { - this._loadData(); - getConfigFlowInProgressCollection(this.hass.connection).refresh(); - }); - // For config entries. Also loading config flow ones for add integration - this.hass.loadBackendTranslation("title", undefined, true); - } - - protected updated(changedProps: PropertyValues) { - super.updated(changedProps); - if (!this._unsubs && changedProps.has("hass")) { - this._loadData(); - } - } - - protected updatePageEl(pageEl) { - pageEl.hass = this.hass; - - pageEl.entityRegistryEntries = this._entityRegistryEntries; - pageEl.configEntries = this._configEntries; - pageEl.narrow = this.narrow; - pageEl.isWide = this.isWide; - pageEl.showAdvanced = this.showAdvanced; - pageEl.route = this.routeTail; - if (this._currentPage === "dashboard") { - pageEl.configEntriesInProgress = this._configEntriesInProgress; - return; - } - - pageEl.configEntryId = this.routeTail.path.substr(1); - pageEl.deviceRegistryEntries = this._deviceRegistryEntries; - pageEl.areas = this._areas; - } - - private _loadData() { - getConfigEntries(this.hass).then((configEntries) => { - this._configEntries = configEntries.sort((conf1, conf2) => - compare(conf1.domain + conf1.title, conf2.domain + conf2.title) - ); - }); - if (this._unsubs) { - return; - } - this._unsubs = [ - subscribeAreaRegistry(this.hass.connection, (areas) => { - this._areas = areas; - }), + public hassSubscribe(): UnsubscribeFunc[] { + return [ subscribeEntityRegistry(this.hass.connection, (entries) => { this._entityRegistryEntries = entries; }), @@ -153,6 +99,563 @@ class HaConfigIntegrations extends HassRouterPage { }), ]; } + + protected firstUpdated(changed: PropertyValues) { + super.firstUpdated(changed); + this._loadConfigEntries(); + this.hass.loadBackendTranslation("title", undefined, true); + } + + protected updated(changed: PropertyValues) { + super.updated(changed); + if ( + this._searchParms.has("config_entry") && + changed.has("_configEntries") && + !(changed.get("_configEntries") as ConfigEntry[]).length && + this._configEntries.length + ) { + afterNextRender(() => { + const card = this.shadowRoot!.getElementById( + this._searchParms.get("config_entry")! + ); + if (card) { + card.scrollIntoView(); + card.classList.add("highlight"); + } + }); + } + } + + protected render(): TemplateResult { + return html` + + + + + + ${this.hass.localize( + this._showIgnored + ? "ui.panel.config.integrations.ignore.hide_ignored" + : "ui.panel.config.integrations.ignore.show_ignored" + )} + + + + +
+ ${this._showIgnored + ? this._configEntries + .filter((item) => item.source === "ignore") + .map( + (item: ConfigEntry) => html` + +
+ ${this.hass.localize( + "ui.panel.config.integrations.ignore.ignored" + )} +
+
+
+ +
+

+ ${domainToName(this.hass.localize, item.domain)} +

+ ${this.hass.localize( + "ui.panel.config.integrations.ignore.stop_ignore" + )} +
+
+ ` + ) + : ""} + ${this._configEntriesInProgress.length + ? this._configEntriesInProgress.map( + (flow) => html` + +
+ ${this.hass.localize( + "ui.panel.config.integrations.discovered" + )} +
+
+
+ +
+

+ ${localizeConfigFlowTitle(this.hass.localize, flow)} +

+ + ${this.hass.localize( + "ui.panel.config.integrations.configure" + )} + + ${DISCOVERY_SOURCES.includes(flow.context.source) && + flow.context.unique_id + ? html` + + ${this.hass.localize( + "ui.panel.config.integrations.ignore.ignore" + )} + + ` + : ""} +
+
+ ` + ) + : ""} + ${this._configEntries.length + ? this._configEntries.map((item: any) => { + const devices = this._getDevices(item); + const entities = this._getEntities(item); + return item.source === "ignore" + ? "" + : html` + +
+
+ +
+

+ ${domainToName(this.hass.localize, item.domain)} +

+

+ ${item.title} +

+ ${devices.length || entities.length + ? html` +
+ ${devices.length + ? html` + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.devices", + "count", + devices.length + )} + ` + : ""} + ${devices.length && entities.length + ? "and" + : ""} + ${entities.length + ? html` + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.entities", + "count", + entities.length + )} + ` + : ""} +
+ ` + : ""} +
+
+
+ ${this.hass.localize( + "ui.panel.config.integrations.config_entry.rename" + )} + ${item.supports_options + ? html` + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.options" + )} + ` + : ""} +
+ + + + + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.system_options" + )} + + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.delete" + )} + + +
+
+ `; + }) + : html` + +
+

+ ${this.hass.localize("ui.panel.config.integrations.none")} +

+

+ ${this.hass.localize( + "ui.panel.config.integrations.no_integrations" + )} +

+ ${this.hass.localize( + "ui.panel.config.integrations.add" + )} +
+
+ `} +
+ +
+ `; + } + + private _loadConfigEntries() { + getConfigEntries(this.hass).then((configEntries) => { + this._configEntries = configEntries.sort((conf1, conf2) => + compare(conf1.domain + conf1.title, conf2.domain + conf2.title) + ); + }); + } + + private _createFlow() { + showConfigFlowDialog(this, { + dialogClosedCallback: () => { + this._loadConfigEntries(); + getConfigFlowInProgressCollection(this.hass.connection).refresh(); + }, + showAdvanced: this.showAdvanced, + }); + // For config entries. Also loading config flow ones for add integration + this.hass.loadBackendTranslation("title", undefined, true); + } + + private _continueFlow(ev: Event) { + showConfigFlowDialog(this, { + continueFlowId: (ev.target! as any).flowId, + dialogClosedCallback: () => { + this._loadConfigEntries(); + getConfigFlowInProgressCollection(this.hass.connection).refresh(); + }, + }); + } + + private _ignoreFlow(ev: Event) { + const flow = (ev.target! as any).flow; + showConfirmationDialog(this, { + title: this.hass!.localize( + "ui.panel.config.integrations.ignore.confirm_ignore_title", + "name", + localizeConfigFlowTitle(this.hass.localize, flow) + ), + text: this.hass!.localize( + "ui.panel.config.integrations.ignore.confirm_ignore" + ), + confirmText: this.hass!.localize( + "ui.panel.config.integrations.ignore.ignore" + ), + confirm: () => { + ignoreConfigFlow(this.hass, flow.flow_id); + getConfigFlowInProgressCollection(this.hass.connection).refresh(); + }, + }); + } + + private _toggleShowIgnored() { + this._showIgnored = !this._showIgnored; + } + + private async _removeIgnoredIntegration(ev: Event) { + const entry = (ev.target! as any).entry; + showConfirmationDialog(this, { + title: this.hass!.localize( + "ui.panel.config.integrations.ignore.confirm_delete_ignore_title", + "name", + this.hass.localize(`component.${entry.domain}.config.title`) + ), + text: this.hass!.localize( + "ui.panel.config.integrations.ignore.confirm_delete_ignore" + ), + confirmText: this.hass!.localize( + "ui.panel.config.integrations.ignore.stop_ignore" + ), + confirm: async () => { + const result = await deleteConfigEntry(this.hass, entry.entry_id); + if (result.require_restart) { + alert( + this.hass.localize( + "ui.panel.config.integrations.config_entry.restart_confirm" + ) + ); + } + this._loadConfigEntries(); + }, + }); + } + + private _getEntities(configEntry: ConfigEntry): EntityRegistryEntry[] { + if (!this._entityRegistryEntries) { + return []; + } + return this._entityRegistryEntries.filter( + (entity) => entity.config_entry_id === configEntry.entry_id + ); + } + + private _getDevices(configEntry: ConfigEntry): DeviceRegistryEntry[] { + if (!this._deviceRegistryEntries) { + return []; + } + return this._deviceRegistryEntries.filter((device) => + device.config_entries.includes(configEntry.entry_id) + ); + } + + private _onImageLoad(ev) { + ev.target.style.visibility = "initial"; + } + + private _onImageError(ev) { + ev.target.style.visibility = "hidden"; + } + + private _showOptions(ev) { + showOptionsFlowDialog(this, ev.target.closest("ha-card").configEntry); + } + + private _showSystemOptions(ev) { + showConfigEntrySystemOptionsDialog(this, { + entry: ev.target.closest("ha-card").configEntry, + }); + } + + private async _editEntryName(ev) { + const configEntry = ev.target.closest("ha-card").configEntry; + const newName = await showPromptDialog(this, { + title: this.hass.localize("ui.panel.config.integrations.rename_dialog"), + defaultValue: configEntry.title, + inputLabel: this.hass.localize( + "ui.panel.config.integrations.rename_input_label" + ), + }); + if (!newName) { + return; + } + const newEntry = await updateConfigEntry(this.hass, configEntry.entry_id, { + title: newName, + }); + this._configEntries = this._configEntries!.map((entry) => + entry.entry_id === newEntry.entry_id ? newEntry : entry + ); + } + + private async _removeIntegration(ev) { + const entryId = ev.target.closest("ha-card").configEntry.entry_id; + + const confirmed = await showConfirmationDialog(this, { + text: this.hass.localize( + "ui.panel.config.integrations.config_entry.delete_confirm" + ), + }); + + if (!confirmed) { + return; + } + + deleteConfigEntry(this.hass, entryId).then((result) => { + this._configEntries = this._configEntries.filter( + (entry) => entry.entry_id !== entryId + ); + + if (result.require_restart) { + showAlertDialog(this, { + text: this.hass.localize( + "ui.panel.config.integrations.config_entry.restart_confirm" + ), + }); + } + }); + } + + static get styles(): CSSResult[] { + return [ + haStyle, + css` + .container { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + grid-gap: 16px 16px; + padding: 16px; + margin-bottom: 64px; + } + ha-card { + display: flex; + flex-direction: column; + justify-content: space-between; + } + ha-card.highlight { + border: 1px solid var(--accent-color); + } + .discovered { + border: 1px solid var(--primary-color); + } + .discovered .header { + background: var(--primary-color); + color: var(--text-primary-color); + padding: 8px; + text-align: center; + } + .ignored { + border: 1px solid var(--light-theme-disabled-color); + } + .ignored .header { + background: var(--light-theme-disabled-color); + color: var(--text-primary-color); + padding: 8px; + text-align: center; + } + .card-content { + padding: 16px; + text-align: center; + } + ha-card.integration .card-content { + padding-bottom: 3px; + } + .card-actions { + border-top: none; + display: flex; + justify-content: space-between; + align-items: center; + padding-right: 5px; + } + .helper { + display: inline-block; + height: 100%; + vertical-align: middle; + } + .image { + display: flex; + align-items: center; + justify-content: center; + height: 60px; + margin-bottom: 16px; + vertical-align: middle; + } + img { + max-height: 60px; + max-width: 90%; + } + a { + color: var(--primary-color); + } + h1 { + margin-bottom: 0; + } + h2 { + margin-top: 0; + } + ha-fab { + position: fixed; + bottom: 16px; + right: 16px; + z-index: 1; + } + ha-fab[narrow] { + bottom: 84px; + } + ha-fab[rtl] { + right: auto; + left: 16px; + } + paper-menu-button { + color: var(--secondary-text-color); + padding: 0; + } + `, + ]; + } } declare global { diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 5f006a5ce7..3b22b8074a 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -157,7 +157,7 @@ export class HuiCardOptions extends LitElement { } paper-item.delete-item { - color: var(--google-red-500); + color: var(--error-color); } `; } diff --git a/src/resources/markdown_worker.ts b/src/resources/markdown_worker.ts index fd2ee988e3..324b667b08 100644 --- a/src/resources/markdown_worker.ts +++ b/src/resources/markdown_worker.ts @@ -32,6 +32,7 @@ export const renderMarkdown = ( ...whiteListNormal, svg: ["xmlns", "height", "width"], path: ["transform", "stroke", "d"], + img: ["src"], }; } whiteList = whiteListSvg; diff --git a/src/resources/styles.ts b/src/resources/styles.ts index b4e38a73a1..bf7520d65f 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -51,7 +51,11 @@ export const derivedStyles = { export const haStyle = css` :host { - @apply --paper-font-body1; + font-family: var(--paper-font-body1_-_font-family); + -webkit-font-smoothing: var(--paper-font-body1_-_-webkit-font-smoothing); + font-size: var(--paper-font-body1_-_font-size); + font-weight: var(--paper-font-body1_-_font-weight); + line-height: var(--paper-font-body1_-_line-height); } app-header-layout, @@ -73,7 +77,25 @@ export const haStyle = css` } h1 { - @apply --paper-font-title; + font-family: var(--paper-font-title_-_font-family); + -webkit-font-smoothing: var(--paper-font-title_-_-webkit-font-smoothing); + white-space: var(--paper-font-title_-_white-space); + overflow: var(--paper-font-title_-_overflow); + text-overflow: var(--paper-font-title_-_text-overflow); + font-size: var(--paper-font-title_-_font-size); + font-weight: var(--paper-font-title_-_font-weight); + line-height: var(--paper-font-title_-_line-height); + } + + h2 { + font-family: var(--paper-font-subhead_-_font-family); + -webkit-font-smoothing: var(--paper-font-subhead_-_-webkit-font-smoothing); + white-space: var(--paper-font-subhead_-_white-space); + overflow: var(--paper-font-subhead_-_overflow); + text-overflow: var(--paper-font-subhead_-_text-overflow); + font-size: var(--paper-font-subhead_-_font-size); + font-weight: var(--paper-font-subhead_-_font-weight); + line-height: var(--paper-font-subhead_-_line-height); } .secondary { diff --git a/src/translations/en.json b/src/translations/en.json index f39c9260fa..9f9df680cc 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -489,6 +489,10 @@ "config": { "header": "Configure Home Assistant", "introduction": "Here it is possible to configure your components and Home Assistant. Not everything is possible to configure from the UI yet, but we're working on it.", + "filtering": { + "filtering_by": "Filtering by", + "clear": "Clear" + }, "advanced_mode": { "hint_enable": "Missing config options? Enable advanced mode on", "link_profile_page": "your profile page" @@ -1323,9 +1327,12 @@ "integrations": { "caption": "Integrations", "description": "Manage and set up integrations", + "integration": "integration", "discovered": "Discovered", "configured": "Configured", "new": "Set up a new integration", + "add_integration": "Add integration", + "no_integrations": "Seems like you don't have any integations configured yet. Click on the button below to add your first integration!", "note_about_integrations": "Not all integrations can be configured via the UI yet.", "note_about_website_reference": "More are available on the ", "home_assistant_website": "Home Assistant website", @@ -1333,6 +1340,8 @@ "none": "Nothing configured yet", "integration_not_found": "Integration not found.", "details": "Integration details", + "rename_dialog": "Edit the name of this config entry", + "rename_input_label": "Entry name", "ignore": { "ignore": "Ignore", "confirm_ignore_title": "Ignore discovery of {name}?", @@ -1345,11 +1354,12 @@ "stop_ignore": "Stop ignoring" }, "config_entry": { - "settings_button": "Edit settings for {integration}", - "system_options_button": "System options for {integration}", - "delete_button": "Delete {integration}", - "no_devices": "This integration has no devices.", - "no_device": "Entities without devices", + "devices": "{count} {count, plural,\n one {device}\n other {devices}\n}", + "entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}", + "rename": "Rename", + "options": "Options", + "system_options": "System options", + "delete": "Delete", "delete_confirm": "Are you sure you want to delete this integration?", "restart_confirm": "Restart Home Assistant to finish removing this integration", "manuf": "by {manufacturer}", From 9a000781699842601f222fb41cc28c081b53d0ed Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 22 Apr 2020 12:01:43 +0200 Subject: [PATCH 34/36] Display MQTT debug info (#5375) * Add MQTT debug info * Refactor * Fix mistake * Rewrite, improve display. * Tweak translations * Add mqtt-payload.ts * Apply suggestions from code review Co-Authored-By: Zack Arnett * Tweak after adding review comments. * Rewrite to only render the messages when details is opened * Adapt to core PR #33752 * Address review comments * Lint * Lint * Address review comments Co-authored-by: Zack Arnett --- src/data/mqtt.ts | 34 +++ .../dialog-mqtt-device-debug-info.ts | 215 ++++++++++++++++++ .../mqtt-discovery-payload.ts | 49 ++++ .../mqtt-messages.ts | 130 +++++++++++ .../show-dialog-mqtt-device-debug-info.ts | 22 ++ .../device-detail/ha-device-card-mqtt.ts | 27 ++- src/translations/en.json | 11 + 7 files changed, 479 insertions(+), 9 deletions(-) create mode 100644 src/dialogs/mqtt-device-debug-info-dialog/dialog-mqtt-device-debug-info.ts create mode 100644 src/dialogs/mqtt-device-debug-info-dialog/mqtt-discovery-payload.ts create mode 100644 src/dialogs/mqtt-device-debug-info-dialog/mqtt-messages.ts create mode 100644 src/dialogs/mqtt-device-debug-info-dialog/show-dialog-mqtt-device-debug-info.ts diff --git a/src/data/mqtt.ts b/src/data/mqtt.ts index d91b32ce13..d00f9f2415 100644 --- a/src/data/mqtt.ts +++ b/src/data/mqtt.ts @@ -7,6 +7,31 @@ export interface MQTTMessage { retain: number; } +export interface MQTTTopicDebugInfo { + topic: string; + messages: MQTTMessage[]; +} + +export interface MQTTDiscoveryDebugInfo { + topic: string; + payload: string; +} + +export interface MQTTEntityDebugInfo { + entity_id: string; + discovery_data: MQTTDiscoveryDebugInfo; + subscriptions: MQTTTopicDebugInfo[]; +} + +export interface MQTTTriggerDebugInfo { + discovery_data: MQTTDiscoveryDebugInfo; +} + +export interface MQTTDeviceDebugInfo { + entities: MQTTEntityDebugInfo[]; + triggers: MQTTTriggerDebugInfo[]; +} + export const subscribeMQTTTopic = ( hass: HomeAssistant, topic: string, @@ -26,3 +51,12 @@ export const removeMQTTDeviceEntry = ( type: "mqtt/device/remove", device_id: deviceId, }); + +export const fetchMQTTDebugInfo = ( + hass: HomeAssistant, + deviceId: string +): Promise => + hass.callWS({ + type: "mqtt/device/debug_info", + device_id: deviceId, + }); diff --git a/src/dialogs/mqtt-device-debug-info-dialog/dialog-mqtt-device-debug-info.ts b/src/dialogs/mqtt-device-debug-info-dialog/dialog-mqtt-device-debug-info.ts new file mode 100644 index 0000000000..80ce1a52ef --- /dev/null +++ b/src/dialogs/mqtt-device-debug-info-dialog/dialog-mqtt-device-debug-info.ts @@ -0,0 +1,215 @@ +import { + LitElement, + css, + html, + CSSResult, + TemplateResult, + customElement, + property, +} from "lit-element"; +import "../../components/ha-dialog"; +import "../../components/ha-switch"; +import { computeDeviceName } from "../../data/device_registry"; +import { computeStateName } from "../../common/entity/compute_state_name"; +import { haStyleDialog } from "../../resources/styles"; +import type { HaSwitch } from "../../components/ha-switch"; +import { HomeAssistant } from "../../types"; +import { MQTTDeviceDebugInfoDialogParams } from "./show-dialog-mqtt-device-debug-info"; +import { MQTTDeviceDebugInfo, fetchMQTTDebugInfo } from "../../data/mqtt"; +import "./mqtt-messages"; +import "./mqtt-discovery-payload"; + +@customElement("dialog-mqtt-device-debug-info") +class DialogMQTTDeviceDebugInfo extends LitElement { + public hass!: HomeAssistant; + + @property() private _params?: MQTTDeviceDebugInfoDialogParams; + + @property() private _debugInfo?: MQTTDeviceDebugInfo; + + @property() private _showAsYaml = true; + + @property() private _showDeserialized = true; + + public async showDialog( + params: MQTTDeviceDebugInfoDialogParams + ): Promise { + this._params = params; + fetchMQTTDebugInfo(this.hass, params.device.id).then((results) => { + this._debugInfo = results; + }); + } + + protected render(): TemplateResult { + if (!this._params || !this._debugInfo) { + return html``; + } + + return html` + +

+ ${this.hass!.localize( + "ui.dialogs.mqtt_device_debug_info.payload_display" + )} +

+ + ${this.hass!.localize( + "ui.dialogs.mqtt_device_debug_info.deserialize" + )} + + + ${this.hass!.localize( + "ui.dialogs.mqtt_device_debug_info.show_as_yaml" + )} + +

+ ${this.hass!.localize("ui.dialogs.mqtt_device_debug_info.entities")} +

+
    + ${this._debugInfo.entities.length + ? this._renderEntities() + : html` + ${this.hass!.localize( + "ui.dialogs.mqtt_device_debug_info.no_entities" + )} + `} +
+

+ ${this.hass!.localize("ui.dialogs.mqtt_device_debug_info.triggers")} +

+
    + ${this._debugInfo.triggers.length + ? this._renderTriggers() + : html` + ${this.hass!.localize( + "ui.dialogs.mqtt_device_debug_info.no_triggers" + )} + `} +
+ + ${this.hass!.localize("ui.dialogs.generic.close")} + +
+ `; + } + + private _close(): void { + this._params = undefined; + this._debugInfo = undefined; + } + + private _showAsYamlChanged(ev: Event): void { + this._showAsYaml = (ev.target as HaSwitch).checked; + } + + private _showDeserializedChanged(ev: Event): void { + this._showDeserialized = (ev.target as HaSwitch).checked; + } + + private _renderEntities(): TemplateResult { + return html` + ${this._debugInfo!.entities.map( + (entity) => html` +
  • + '${computeStateName(this.hass.states[entity.entity_id])}' + (${entity.entity_id}) +
    MQTT discovery data: +
      +
    • + Topic: + ${entity.discovery_data.topic} +
    • +
    • + + +
    • +
    + Subscribed topics: +
      + ${entity.subscriptions.map( + (topic) => html` +
    • + ${topic.topic} + + +
    • + ` + )} +
    +
  • + ` + )} + `; + } + + private _renderTriggers(): TemplateResult { + return html` + ${this._debugInfo!.triggers.map( + (trigger) => html` +
  • + Discovery topic: + ${trigger.discovery_data.topic} + + +
  • + ` + )} + `; + } + + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + ha-dialog { + --mdc-dialog-max-width: 95%; + --mdc-dialog-min-width: 640px; + } + ha-switch { + margin: 16px; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-mqtt-device-debug-info": DialogMQTTDeviceDebugInfo; + } +} diff --git a/src/dialogs/mqtt-device-debug-info-dialog/mqtt-discovery-payload.ts b/src/dialogs/mqtt-device-debug-info-dialog/mqtt-discovery-payload.ts new file mode 100644 index 0000000000..b000f5499a --- /dev/null +++ b/src/dialogs/mqtt-device-debug-info-dialog/mqtt-discovery-payload.ts @@ -0,0 +1,49 @@ +import { + LitElement, + html, + TemplateResult, + customElement, + property, +} from "lit-element"; +import { safeDump } from "js-yaml"; + +@customElement("mqtt-discovery-payload") +class MQTTDiscoveryPayload extends LitElement { + @property() public payload!: object; + + @property() public showAsYaml = false; + + @property() public summary!: string; + + @property() private _open = false; + + protected render(): TemplateResult { + return html` +
    + + ${this.summary} + + ${this._open ? this._renderPayload() : ""} +
    + `; + } + + private _renderPayload(): TemplateResult { + const payload = this.payload; + return html` + ${this.showAsYaml + ? html`
    ${safeDump(payload)}
    ` + : html`
    ${JSON.stringify(payload, null, 2)}
    `} + `; + } + + private _handleToggle(ev) { + this._open = ev.target.open; + } +} + +declare global { + interface HTMLElementTagNameMap { + "mqtt-discovery-payload": MQTTDiscoveryPayload; + } +} diff --git a/src/dialogs/mqtt-device-debug-info-dialog/mqtt-messages.ts b/src/dialogs/mqtt-device-debug-info-dialog/mqtt-messages.ts new file mode 100644 index 0000000000..c3f3b799ef --- /dev/null +++ b/src/dialogs/mqtt-device-debug-info-dialog/mqtt-messages.ts @@ -0,0 +1,130 @@ +import { + LitElement, + html, + TemplateResult, + customElement, + property, +} from "lit-element"; +import { safeDump } from "js-yaml"; +import { MQTTMessage } from "../../data/mqtt"; + +@customElement("mqtt-messages") +class MQTTMessages extends LitElement { + @property() public messages!: MQTTMessage[]; + + @property() public showAsYaml = false; + + @property() public showDeserialized = false; + + @property() public subscribedTopic!: string; + + @property() public summary!: string; + + @property() private _open = false; + + @property() private _payloadsJson = new WeakMap(); + + @property() private _showTopic = false; + + protected firstUpdated(): void { + this.messages.forEach((message) => { + // If any message's topic differs from the subscribed topic, show topics + payload + if (this.subscribedTopic !== message.topic) { + this._showTopic = true; + } + }); + } + + protected render(): TemplateResult { + return html` +
    + + ${this.summary} + + ${this._open + ? html` +
      + ${this.messages.map( + (message) => html` +
    • + ${this._renderSingleMessage(message)} +
    • + ` + )} +
    + ` + : ""} +
    + `; + } + + private _renderSingleMessage(message): TemplateResult { + const topic = message.topic; + return this._showTopic + ? html` +
      +
    • + Topic: ${topic} +
    • +
    • + Payload: ${this._renderSinglePayload(message)} +
    • +
    + ` + : this._renderSinglePayload(message); + } + + private _renderSinglePayload(message): TemplateResult { + let json; + + if (this.showDeserialized) { + if (!this._payloadsJson.has(message)) { + json = this._tryParseJson(message.payload); + this._payloadsJson.set(message, json); + } else { + json = this._payloadsJson.get(message); + } + } + + return json + ? html` + ${this.showAsYaml + ? html`
    ${safeDump(json)}
    ` + : html`
    ${JSON.stringify(json, null, 2)}
    `} + ` + : html` ${message.payload} `; + } + + private _tryParseJson(payload) { + let jsonPayload = null; + let o = payload; + + // If the payload is a string, determine if the payload is valid JSON and if it + // is, assign the object representation to this._payloadJson. + if (typeof payload === "string") { + try { + o = JSON.parse(payload); + } catch (e) { + o = null; + } + } + // Handle non-exception-throwing cases: + // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking, + // but... JSON.parse(null) returns null, and typeof null === "object", + // so we must check for that, too. Thankfully, null is falsey, so this suffices: + if (o && typeof o === "object") { + jsonPayload = o; + } + return jsonPayload; + } + + private _handleToggle(ev) { + this._open = ev.target.open; + } +} + +declare global { + interface HTMLElementTagNameMap { + "mqtt-messages": MQTTMessages; + } +} diff --git a/src/dialogs/mqtt-device-debug-info-dialog/show-dialog-mqtt-device-debug-info.ts b/src/dialogs/mqtt-device-debug-info-dialog/show-dialog-mqtt-device-debug-info.ts new file mode 100644 index 0000000000..92fe6554cc --- /dev/null +++ b/src/dialogs/mqtt-device-debug-info-dialog/show-dialog-mqtt-device-debug-info.ts @@ -0,0 +1,22 @@ +import { fireEvent } from "../../common/dom/fire_event"; +import { DeviceRegistryEntry } from "../../data/device_registry"; + +export interface MQTTDeviceDebugInfoDialogParams { + device: DeviceRegistryEntry; +} + +export const loadMQTTDeviceDebugInfoDialog = () => + import( + /* webpackChunkName: "dialog-mqtt-device-debug-info" */ "./dialog-mqtt-device-debug-info" + ); + +export const showMQTTDeviceDebugInfoDialog = ( + element: HTMLElement, + mqttDeviceInfoParams: MQTTDeviceDebugInfoDialogParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-mqtt-device-debug-info", + dialogImport: loadMQTTDeviceDebugInfoDialog, + dialogParams: mqttDeviceInfoParams, + }); +}; diff --git a/src/panels/config/devices/device-detail/ha-device-card-mqtt.ts b/src/panels/config/devices/device-detail/ha-device-card-mqtt.ts index cce083ac15..c2d1e9e824 100644 --- a/src/panels/config/devices/device-detail/ha-device-card-mqtt.ts +++ b/src/panels/config/devices/device-detail/ha-device-card-mqtt.ts @@ -1,16 +1,17 @@ -import { - CSSResult, - customElement, - html, - LitElement, - property, - TemplateResult, -} from "lit-element"; import { DeviceRegistryEntry } from "../../../../data/device_registry"; import { removeMQTTDeviceEntry } from "../../../../data/mqtt"; +import { + LitElement, + html, + customElement, + property, + TemplateResult, + CSSResult, +} from "lit-element"; import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box"; -import { haStyle } from "../../../../resources/styles"; +import { showMQTTDeviceDebugInfoDialog } from "../../../../dialogs/mqtt-device-debug-info-dialog/show-dialog-mqtt-device-debug-info"; import { HomeAssistant } from "../../../../types"; +import { haStyle } from "../../../../resources/styles"; @customElement("ha-device-card-mqtt") export class HaDeviceCardMqtt extends LitElement { @@ -20,6 +21,9 @@ export class HaDeviceCardMqtt extends LitElement { protected render(): TemplateResult { return html` + + MQTT Info + ${this.hass.localize("ui.panel.config.devices.delete")} @@ -38,6 +42,11 @@ export class HaDeviceCardMqtt extends LitElement { await removeMQTTDeviceEntry(this.hass!, this.device.id); } + private async _showDebugInfo(): Promise { + const device = this.device; + await showMQTTDeviceDebugInfoDialog(this, { device }); + } + static get styles(): CSSResult { return haStyle; } diff --git a/src/translations/en.json b/src/translations/en.json index 9f9df680cc..26ddad1a5e 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -456,6 +456,17 @@ }, "domain_toggler": { "title": "Toggle Domains" + }, + "mqtt_device_debug_info": { + "title": "{device} debug info", + "deserialize": "Attempt to parse MQTT messages as JSON", + "entities": "Entities", + "no_entities": "No entities", + "no_triggers": "No triggers", + "payload_display": "Payload display", + "recent_messages": "{n} most recently received message(s)", + "show_as_yaml": "Show as YAML", + "triggers": "Triggers" } }, "duration": { From fdf7b516a0ae477355bc8a11bdb6e8452ec08378 Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Wed, 22 Apr 2020 06:13:32 -0400 Subject: [PATCH 35/36] Weather Card: Beautify (#5387) * Weather card * Updates * Remove Precipitation from forecast * Weather Card :) * Fix no breaking changes * Size styles * Space * Fix some overlap * Unavailable * New unavailable * Changed to check if less than day * Updates * oops * Little clean up * styling * Reviews * Fix merge * Lint * eslint * New images * Update src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts Co-Authored-By: Bram Kragten * Reviews * Reviews * Comments Co-authored-by: Bram Kragten --- public/static/images/weather/night.png | Bin 465 -> 648 bytes .../static/images/weather/partly-cloudy.png | Bin 1064 -> 1130 bytes public/static/images/weather/sunny.png | Bin 678 -> 492 bytes src/data/weather.ts | 96 ++- .../cards/hui-weather-forecast-card.ts | 628 ++++++++++-------- src/panels/lovelace/cards/types.ts | 1 + .../hui-weather-forecast-card-editor.ts | 58 +- .../entity-rows/hui-weather-entity-row.ts | 86 +-- src/translations/en.json | 3 +- src/types.ts | 1 + 10 files changed, 470 insertions(+), 403 deletions(-) diff --git a/public/static/images/weather/night.png b/public/static/images/weather/night.png index d7e79d2ac9a7426ee97ffcbb81e6d58ffe189306..d7661fab3f75aaa2835e75dcfc8ea2b527676040 100644 GIT binary patch delta 623 zcmcb}+`&3QrM@@7C&ZP3f#Jc||0nMLIdKPsj^F-$;`Vi>W=-vJr{)cN`zx@lBvmQ|i`ynhey*0?khn;t6ep1xK`*SM9Dm-R#wpD1j?PK_M zWYOXy_mtxg@8F4<@*}uo74y0yiDB$(B2Ar+DzZuYtNoGt82pFjSgXL}&M%e0Yj!Nj zX{%4~dtkaSY4R%GtfGVSnLclRw&+|)>@ptxw65tt4rzB^X{kv49JD6Ge#s$+=9v?j zHo7#Y8FR;OY&j&O5_Lx8+ru8SOI#TXI$c)ZdAFxM{YqWl#e;=^x82~ajrwn2aKZKR z^U1$9->kfK$JBq(@u2)`im;7VZG5*rT&+Xdc`{1YshXL1|zzqjAGQt|059wUuYRxLP;!xV| z>h-K@35TU~YPHURiD{y5!Wegj2CQLP6Xv*)YeN+4)F_pGfs*kZ&rdB0S$3{uwe32N zBO))u++q}^D@CR{>|wS%*}zy@CeOmGGBG*iRm|qH9?k7tai!AjQ|vr`KlpIT?e2!{ zZ>{HcG5FPg{^wZa^LO&wg*z|rQWcPywzly>ft|M8W54~s`#;wiN|>zw;q`2)+c|&F zCQTKd_1?!=ey)?xRF_}xva{FSzHqS&+l~k7`ne_InYvGT?2f+qx5;wZ>yv*OUMvf; U{nS%;9T>zopr0BO?MRsaA1 diff --git a/public/static/images/weather/partly-cloudy.png b/public/static/images/weather/partly-cloudy.png index a39a400ba1c6aa2898b237cac148797b9efc4330..6c59f6cc936b1d7b4ebb67e98e679c11e2ece5ef 100644 GIT binary patch literal 1130 zcmXw1X;4#F6b^*N27^F`F$FAvVX*{lKz|5?vL&)e;jvZ0s-SkPK!IVAH7rR8AW&%$ zMuP~&ZZcD9ktxe4Yq5m{Ww8(Ln4uYs$4GL z+}zyS+5#A4Pz6A#RH6bZf*@cE9zZxGYo|R9I39@56M)^7Cg7u1s{satL%CK6B%ZSW z1DU1*2)dv%Zs?>tdfuvzP_$dD8MIx7O+?hXg~|hW$@Sr zyefs?$zk5MxL>(cs-92Kh_1@u@tw8jszrusF;_Dig$RQXVIa+sv;T9U^ze`f%nQX1 zqE;z(-iwC(#m^e6vTcb3wM--!_?elU6k(*1yno$ZQ&F0KCjtugIB92n+|? z)ZHSOiFr!@X6nv3j?P#~ZA0W;{i9g~`<|bafnG)p$>cA(;^bF~L)95jbGT?Y=_amI z@NedAy0_npp%5MSRsRM$$J_^TE}OV}EzhSO{q)h84R1S_jpJ3Z^7-a7%S)jVE}eY^ zr-z}!J(gou-|`#B?@RAd`z*-k^arg<1lJ!A1(0D^ro++2>U1`F$h+@i&wOFF{zG;i zr=0IWbRPAJ?Y0`3tdF+fpW*ja1>Y*iPVQ2REGfEb*s9`hO_rQPi?L$kk96b}r|Q#oHF204UB zAAVQfbEf)c=ZUW(dq^C84Q-xuR%&7Agh{Ke=v^auMGp>Ea^K=l1(&$gy|L2mXCTCZ zbYd%ZspzwEJ_#mqV~?G?@6T<+wmz7XVD5VQ3FG?ts99E4#;FdhY?(0lQS9n$rC~aS zsx|u2X&z#v-;&4Yy*9I{3Hr5VQ4*e)MqY-TGej&xh;j-skbY~g!|VOW6kKymAU%ZE I;v38S4^xPX^8f$< delta 1043 zcmaFGv4UfQO1*M`Plzi65_tLYB@&MT$c2EvH*J985cbcXKjDlQFJ1t}zhAKi3jX-< zfA=dFJHc_ zU%&qGVbdp1o&YtRKYt#m`rEf}K(m0V-#$GI6o2^O&c{n0UoTm`KWlma{(Ydb-`8y} zZ#4oc{{R2~u3fv{ymW!qfKouafF{3v`}Y0& z_x10d?)&)hEaj?aro`Dn^m(M zB-%s+U1Fk|a+7;5&RF_#+LGV+?Z5G^>})J)i4WGCpS(w|e*OLb{K{eL zc1G3AeAj#Y@yXr2Sw1tr6kNKNT(<1+roP9W^A_5QvMg*#N?!7~r_Je!#-#k$DsS7F zf~K6F%+@HnTaz!Ue(f}+u)gvVtHtkyq8F@Ccy=>>?!j#;o+StW`c6puI5|VdTo}k&V44GX(9(#NAU`0 z7zGzNNPLK*Z)p&nCNI(cUXPr{fr|`+ZB$UX`SNFM*7bVAuNt9oDIrbEvpt|cE-oar7RbGZ41#BR^}%N{&`_|9LPtkEPo zFENF8PG}w1`=(hU22Ne!6~bIW_0Q7<+G-98Yn<>&5Mq;lw6pk`)a;e(T4`1oEu zV4Adh?lM!kp0N2-$NB!id3g$-?=I$Q+m`+O4ddy2ttFW)a_V*7Tfo(GiIJzf1=);T3K0RU>HGb;c9 diff --git a/public/static/images/weather/sunny.png b/public/static/images/weather/sunny.png index 6c67835dcede3fac5163abd0eaa24b5073e7226a..671611b73bbf096533db121736b2c08d044e2aa3 100644 GIT binary patch delta 466 zcmZ3+`i6OeN_|v-Plzi61H->tHvcc${k>`Z@21UPAp4fhUmydDK!Sg6+WZG`t^Z#) z1Ck)ATh_mCfK>j!ZT@J zbEECgkFO5win3}IUX+#QUTY^t2UitZ+#&){nmx5W{&t@CADoDHzQe?`Lp?TZR*z)S2QH5 zoZrmiyz|0ES)F62;|*jt?_vset+#O4#>#5us=rGnr_z1594FhYRF4T4-NZct-k2vj zO{(O+py0Wgb%RIJUZ(>oe3>d9OQk%s3K>4Cckl=Pkv`g~;+Og{RVXg~>$#>)Twb#l ztnfO$>r3K9yIj9NJLGgPJ)i4l&~wOJ?6}u#ox<7b*(UGrRo%0UNZf3Dsr9S+j=!zz zc7AR=94Pbs|B1&M_pD^v*Cnc|*}hM{zvkuRJNhT)@b&Pm_+AVQTLw>8KbLh*2~7ah CYu~5< delta 654 zcmaFEyo_~%N_~ESPlzi6Zt&-Z&5Psae{b3V8Ta>_{J3iUqz%%d;B{A09LXDgYv($i?fOH2yqBB_I$i3bhTDpVo`guli{(0MTLQm#!B)lt<4@3L_g7GU|>At z>Eaj?aro`^(`8Kt5-bTSLIO;I0(-KzR{l@Vkx*jf*ZBEzQTMqzJ9WXYFMLljeT)g7 z8?N@8tBJeV_Fbs{@57~5ljK^ZIxLn72zFF)et zdtzFzVCFhC)%y{Pu8U_S9Z}2S^pbbVVDY-owTAi0Da}d&Gvzmbt(O@zy$nBP`Q1TS z_rqJh6h@X?j1!oceq}l_PKwqIU{7#b!upB9r$g$&ijIkaEDiyUJwe-hg>+fz~zXBhuT&G=l% zRczhYpR;ULApz$DzVo#C(g zhXVFfatG${D_+cJ;Mf`c|8zdXJ6rXfmdmVbE^cRFIc~?skfGL6FEHnqn1Pes$3JuH zuCN|jFr(uCHu;L$hx2OZ#FzbM=sBRka`d--?8f}xUm3VF7##|j4TIwMe_`Cib { + const extrema = getWeatherExtrema(hass, stateObj); + + if (extrema) { + return extrema; + } + + let value: number; + let attribute: string; + + if ( + stateObj.attributes.forecast?.length && + stateObj.attributes.forecast[0].precipitation !== undefined && + stateObj.attributes.forecast[0].precipitation !== null + ) { + value = stateObj.attributes.forecast[0].precipitation!; + attribute = "precipitation"; + } else if ("humidity" in stateObj.attributes) { + value = stateObj.attributes.humidity!; + attribute = "humidity"; + } else { + return undefined; + } + + return ` + ${hass!.localize( + `ui.card.weather.attributes.${attribute}` + )} ${value} ${getWeatherUnit(hass!, attribute)} + `; +}; + +const getWeatherExtrema = ( + hass: HomeAssistant, + stateObj: WeatherEntity +): string | undefined => { + if (!stateObj.attributes.forecast?.length) { + return undefined; + } + + let tempLow: number | undefined; + let tempHigh: number | undefined; + const today = new Date().getDate(); + + for (const forecast of stateObj.attributes.forecast!) { + if (new Date(forecast.datetime).getDate() !== today) { + break; + } + if (!tempHigh || forecast.temperature > tempHigh) { + tempHigh = forecast.temperature; + } + if (!tempLow || (forecast.templow && forecast.templow < tempLow)) { + tempLow = forecast.templow; + } + if (!forecast.templow && (!tempLow || forecast.temperature < tempLow)) { + tempLow = forecast.temperature; + } + } + + if (!tempLow && !tempHigh) { + return undefined; + } + + const unit = getWeatherUnit(hass!, "temperature"); + + return ` + ${ + tempHigh + ? ` + ${hass!.localize(`ui.card.weather.high`)} ${tempHigh} ${unit} + ` + : "" + } + ${tempLow && tempHigh ? " / " : ""} + ${ + tempLow + ? ` + ${hass!.localize(`ui.card.weather.low`)} ${tempLow} ${unit} + ` + : "" + } + `; +}; diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts index 81e269089a..023633dd17 100644 --- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts +++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts @@ -8,58 +8,32 @@ import { PropertyValues, TemplateResult, } from "lit-element"; -import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; -import { fireEvent } from "../../../common/dom/fire_event"; -import { toggleAttribute } from "../../../common/dom/toggle_attribute"; -import { computeStateName } from "../../../common/entity/compute_state_name"; -import { isValidEntityId } from "../../../common/entity/valid_entity_id"; -import { computeRTL } from "../../../common/util/compute_rtl"; + +import "../../../components/ha-icon"; import "../../../components/ha-card"; -import { HomeAssistant } from "../../../types"; -import { actionHandler } from "../common/directives/action-handler-directive"; +import "../components/hui-warning"; + +import { WeatherForecastCardConfig } from "./types"; +import { LovelaceCard, LovelaceCardEditor } from "../types"; +import { HomeAssistant, WeatherEntity } from "../../../types"; import { findEntities } from "../common/find-entites"; import { hasConfigOrEntityChanged } from "../common/has-changed"; -import "../components/hui-warning"; -import { LovelaceCard, LovelaceCardEditor } from "../types"; -import { WeatherForecastCardConfig } from "./types"; +import { actionHandler } from "../common/directives/action-handler-directive"; +import { isValidEntityId } from "../../../common/entity/valid_entity_id"; +import { computeStateName } from "../../../common/entity/compute_state_name"; +import { fireEvent } from "../../../common/dom/fire_event"; +import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; +import { debounce } from "../../../common/util/debounce"; +import { UNAVAILABLE } from "../../../data/entity"; +import { + weatherIcons, + getSecondaryWeatherAttribute, + getWeatherUnit, + weatherImages, +} from "../../../data/weather"; +import { stateIcon } from "../../../common/entity/state_icon"; -const cardinalDirections = [ - "N", - "NNE", - "NE", - "ENE", - "E", - "ESE", - "SE", - "SSE", - "S", - "SSW", - "SW", - "WSW", - "W", - "WNW", - "NW", - "NNW", - "N", -]; - -const weatherIcons = { - "clear-night": "hass:weather-night", - cloudy: "hass:weather-cloudy", - exceptional: "hass:alert-circle-outline", - fog: "hass:weather-fog", - hail: "hass:weather-hail", - lightning: "hass:weather-lightning", - "lightning-rainy": "hass:weather-lightning-rainy", - partlycloudy: "hass:weather-partly-cloudy", - pouring: "hass:weather-pouring", - rainy: "hass:weather-rainy", - snowy: "hass:weather-snowy", - "snowy-rainy": "hass:weather-snowy-rainy", - sunny: "hass:weather-sunny", - windy: "hass:weather-windy", - "windy-variant": "hass:weather-windy-variant", -}; +const DAY_IN_MILLISECONDS = 86400000; @customElement("hui-weather-forecast-card") class HuiWeatherForecastCard extends LitElement implements LovelaceCard { @@ -92,8 +66,18 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { @property() private _config?: WeatherForecastCardConfig; + @property({ type: Boolean, reflect: true, attribute: "narrow" }) + private _narrow = false; + + private _resizeObserver?: ResizeObserver; + + public connectedCallback(): void { + super.connectedCallback(); + this.updateComplete.then(() => this._measureCard()); + } + public getCardSize(): number { - return 4; + return this._config?.show_forecast !== false ? 4 : 2; } public setConfig(config: WeatherForecastCardConfig): void { @@ -112,6 +96,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { if (!this._config || !this.hass) { return; } + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; const oldConfig = changedProps.get("_config") as | WeatherForecastCardConfig @@ -125,10 +110,6 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { ) { applyThemesOnElement(this, this.hass.themes, this._config.theme); } - - if (changedProps.has("hass")) { - toggleAttribute(this, "rtl", computeRTL(this.hass!)); - } } protected render(): TemplateResult { @@ -136,7 +117,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { return html``; } - const stateObj = this.hass.states[this._config.entity]; + const stateObj = this.hass.states[this._config.entity] as WeatherEntity; if (!stateObj) { return html` @@ -150,9 +131,33 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { `; } - const forecast = stateObj.attributes.forecast - ? stateObj.attributes.forecast.slice(0, 5) - : undefined; + if (stateObj.state === UNAVAILABLE) { + return html` + + ${this.hass.localize( + "ui.panel.lovelace.warning.entity_unavailable", + "entity", + `${computeStateName(stateObj)} (${this._config.entity})` + )} + + `; + } + + const forecast = + this._config?.show_forecast !== false && + stateObj.attributes.forecast?.length + ? stateObj.attributes.forecast.slice(0, this._narrow ? 3 : 5) + : undefined; + + let hourly: boolean | undefined; + + if (forecast?.length && forecast?.length > 1) { + const date1 = new Date(forecast[0].datetime); + const date2 = new Date(forecast[1].datetime); + const timeDiff = date2.getTime() - date1.getTime(); + + hourly = timeDiff < DAY_IN_MILLISECONDS; + } return html` -
    - ${this.hass.localize(`state.weather.${stateObj.state}`) || - stateObj.state} -
    - ${(this._config && this._config.name) || computeStateName(stateObj)} -
    -
    -
    -
    - ${stateObj.state in weatherIcons - ? html` - - ` - : ""} -
    - ${stateObj.attributes.temperature}${this.getUnit("temperature")} +
    + ${stateObj.state in weatherImages + ? html` + + ` + : html` + + `} +
    +
    + ${this._config.name || computeStateName(stateObj)} +
    +
    + ${this.hass.localize(`state.weather.${stateObj.state}`) || + stateObj.state}
    -
    - ${this._showValue(stateObj.attributes.pressure) - ? html` -
    - ${this.hass.localize( - "ui.card.weather.attributes.air_pressure" - )}: - - ${stateObj.attributes.pressure} - ${this.getUnit("air_pressure")} - -
    - ` - : ""} - ${this._showValue(stateObj.attributes.humidity) - ? html` -
    - ${this.hass.localize( - "ui.card.weather.attributes.humidity" - )}: - ${stateObj.attributes.humidity} % -
    - ` - : ""} - ${this._showValue(stateObj.attributes.wind_speed) - ? html` -
    - ${this.hass.localize( - "ui.card.weather.attributes.wind_speed" - )}: - - ${stateObj.attributes.wind_speed} - ${this.getUnit("length")}/h - - ${this.getWindBearing(stateObj.attributes.wind_bearing)} -
    - ` - : ""} +
    +
    +
    + ${stateObj.attributes.temperature}${getWeatherUnit(this.hass, "temperature")} +
    +
    + ${getSecondaryWeatherAttribute(this.hass, stateObj)}
    - ${forecast - ? html` -
    - ${forecast.map( - (item) => html` -
    -
    - ${new Date(item.datetime).toLocaleDateString( - this.hass!.language, - { weekday: "short" } - )}
    - ${!this._showValue(item.templow) - ? html` - ${new Date(item.datetime).toLocaleTimeString( - this.hass!.language, - { - hour: "numeric", - } - )} - ` - : ""} -
    - ${this._showValue(item.condition) - ? html` -
    - -
    - ` - : ""} - ${this._showValue(item.temperature) - ? html` -
    - ${item.temperature} - ${this.getUnit("temperature")} -
    - ` - : ""} - ${this._showValue(item.templow) - ? html` -
    - ${item.templow} ${this.getUnit("temperature")} -
    - ` - : ""} - ${this._showValue(item.precipitation) - ? html` -
    - ${item.precipitation} - ${this.getUnit("precipitation")} -
    - ` - : ""} -
    - ` - )} -
    - ` - : ""}
    + ${forecast + ? html` +
    + ${forecast.map( + (item) => html` +
    +
    + ${hourly + ? html` + ${new Date(item.datetime).toLocaleTimeString( + this.hass!.language, + { + hour: "numeric", + } + )} + ` + : html` + ${new Date(item.datetime).toLocaleDateString( + this.hass!.language, + { weekday: "short" } + )} + `} +
    + ${item.condition !== undefined && item.condition !== null + ? html` +
    + ${item.condition in weatherImages + ? html` + + ` + : item.condition in weatherIcons + ? html` + + ` + : ""} +
    + ` + : ""} + ${item.temperature !== undefined && + item.temperature !== null + ? html` +
    + ${item.temperature}° +
    + ` + : ""} + ${item.templow !== undefined && item.templow !== null + ? html` +
    + ${item.templow}° +
    + ` + : ""} +
    + ` + )} +
    + ` + : ""} `; } @@ -292,177 +274,239 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { return hasConfigOrEntityChanged(this, changedProps); } + protected firstUpdated(): void { + this._attachObserver(); + } + private _handleAction(): void { fireEvent(this, "hass-more-info", { entityId: this._config!.entity }); } - private getUnit(measure: string): string { - const lengthUnit = this.hass!.config.unit_system.length || ""; - switch (measure) { - case "air_pressure": - return lengthUnit === "km" ? "hPa" : "inHg"; - case "length": - return lengthUnit; - case "precipitation": - return lengthUnit === "km" ? "mm" : "in"; - default: - return this.hass!.config.unit_system[measure] || ""; + private _attachObserver(): void { + if (typeof ResizeObserver !== "function") { + import("resize-observer").then((modules) => { + modules.install(); + this._attachObserver(); + }); + return; } + + this._resizeObserver = new ResizeObserver( + debounce(() => this._measureCard(), 250, false) + ); + + const card = this.shadowRoot!.querySelector("ha-card"); + // If we show an error or warning there is no ha-card + if (!card) { + return; + } + this._resizeObserver.observe(card); } - private windBearingToText(degree: string): string { - const degreenum = parseInt(degree, 10); - if (isFinite(degreenum)) { - // eslint-disable-next-line no-bitwise - return cardinalDirections[(((degreenum + 11.25) / 22.5) | 0) % 16]; + private _measureCard() { + this._narrow = this.offsetWidth < 375; + if (this.offsetWidth < 300) { + this.setAttribute("verynarrow", ""); + } else { + this.removeAttribute("verynarrow"); } - return degree; - } - - private getWindBearing(bearing: string): string { - if (bearing != null) { - const cardinalDirection = this.windBearingToText(bearing); - return `(${ - this.hass!.localize( - `ui.card.weather.cardinal_direction.${cardinalDirection.toLowerCase()}` - ) || cardinalDirection - })`; + if (this.offsetWidth < 200) { + this.setAttribute("veryverynarrow", ""); + } else { + this.removeAttribute("veryverynarrow"); } - return ``; - } - - private _showValue(item: string): boolean { - return typeof item !== "undefined" && item !== null; } static get styles(): CSSResult { return css` :host { + display: block; + } + + ha-card { cursor: pointer; + padding: 16px; } .content { - padding: 0 20px 20px; - } - - ha-icon { - color: var(--paper-item-icon-color); - } - - .header { - font-family: var(--paper-font-headline_-_font-family); - -webkit-font-smoothing: var( - --paper-font-headline_-_-webkit-font-smoothing - ); - font-size: var(--paper-font-headline_-_font-size); - font-weight: var(--paper-font-headline_-_font-weight); - letter-spacing: var(--paper-font-headline_-_letter-spacing); - line-height: var(--paper-font-headline_-_line-height); - text-rendering: var( - --paper-font-common-expensive-kerning_-_text-rendering - ); - opacity: var(--dark-primary-opacity); - padding: 24px 16px 16px; display: flex; - align-items: baseline; + flex-wrap: nowrap; + justify-content: space-between; + align-items: center; } - .name { - margin-left: 16px; - font-size: 16px; - color: var(--secondary-text-color); + .icon-info { + display: flex; + align-items: center; + min-width: 0; + flex: 1; } - :host([rtl]) .name { - margin-left: 0px; + .weather-image, + .weather-icon { + flex: 0 0 66px; margin-right: 16px; } - .now { + .weather-icon { + --iron-icon-width: 66px; + --iron-icon-height: 66px; + } + + .info { + overflow: hidden; + } + + .name { + font-size: 16px; + color: var(--secondary-text-color); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .state { + font-size: 28px; + line-height: 1.2; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .temp-attribute { display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; + flex-direction: column; + align-items: flex-end; } - .main { - display: flex; - align-items: center; - margin-right: 32px; - } - - :host([rtl]) .main { - margin-right: 0px; - } - - .main ha-icon { - --iron-icon-height: 72px; - --iron-icon-width: 72px; - margin-right: 8px; - } - - :host([rtl]) .main ha-icon { - margin-right: 0px; - } - - .main .temp { - font-size: 52px; - line-height: 1em; + .temp-attribute .temp { position: relative; + font-size: 38px; + line-height: 1; + margin-right: 24px; } - :host([rtl]) .main .temp { - direction: ltr; - margin-right: 28px; - } - - .main .temp span { - font-size: 24px; - line-height: 1em; + .temp-attribute .temp span { position: absolute; + font-size: 24px; top: 4px; } - .measurand { - display: inline-block; - } - - :host([rtl]) .measurand { - direction: ltr; - } - .forecast { - margin-top: 16px; display: flex; justify-content: space-between; + padding-top: 16px; } - .forecast div { - flex: 0 0 auto; + .forecast > div { text-align: center; } - .forecast .icon { + .forecast .icon, + .forecast .temp { margin: 4px 0; - text-align: center; } - :host([rtl]) .forecast .temp { - direction: ltr; + .forecast .temp { + font-size: 16px; } - .weekday { - font-weight: bold; + .forecast-image-icon { + padding-top: 4px; + padding-bottom: 4px; } - .attributes, - .templow, - .precipitation { + .forecast-image { + width: 40px; + } + + .forecast-icon { + --iron-icon-width: 40px; + --iron-icon-height: 40px; + } + + .attribute { + line-height: 1; + } + + .attribute, + .templow { color: var(--secondary-text-color); } - :host([rtl]) .precipitation { - direction: ltr; + :host([narrow]) .weather-image { + flex: 0 0 58px; + } + + :host([narrow]) .weather-icon { + --iron-icon-width: 58px; + --iron-icon-height: 58px; + } + + :host([narrow]) .state { + font-size: 22px; + } + + :host([narrow]) .temp-attribute .temp { + font-size: 44px; + margin-right: 18px; + } + + :host([narrow]) .temp-attribute .temp span { + font-size: 18px; + top: 3px; + } + + :host([narrow]) .attribute { + display: none; + } + + :host([narrow]) .forecast { + justify-content: space-around; + } + + :host([veryVeryNarrow]) .content { + flex-wrap: wrap; + justify-content: center; + } + + :host([veryNarrow]) .icon-info { + flex: initial; + } + + :host([narrow]) .weather-image { + flex: 0 0 48px; + } + + :host([narrow]) .weather-icon { + --iron-icon-width: 48px; + --iron-icon-height: 48px; + } + + :host([veryNarrow]) .info { + display: none; + } + + :host([veryNarrow]) .temp-attribute .temp { + font-size: 36px; + } + + :host([veryNarrow]) .temp-attribute .temp span { + top: 2px; + } + + :host([veryVeryNarrow]) .temp-attribute { + padding-top: 4px; + } + + .unavailable { + height: 100px; + display: flex; + justify-content: center; + align-items: center; + font-size: 16px; + padding: 10px 20px; + text-align: center; } `; } diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index 233cc65e3a..5dd1c46ac1 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -274,4 +274,5 @@ export interface ThermostatCardConfig extends LovelaceCardConfig { export interface WeatherForecastCardConfig extends LovelaceCardConfig { entity: string; name?: string; + show_forecast?: boolean; } diff --git a/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts index 2bf907a919..f8d8415bbe 100644 --- a/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts @@ -7,12 +7,14 @@ import { } from "lit-element"; import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/entity/ha-entity-picker"; +import "../../../../components/ha-switch"; + +import { EntitiesEditorEvent, EditorTarget } from "../types"; import { HomeAssistant } from "../../../../types"; import { WeatherForecastCardConfig } from "../../cards/types"; import { struct } from "../../common/structs/struct"; import "../../components/hui-theme-select-editor"; import { LovelaceCardEditor } from "../../types"; -import { EditorTarget, EntitiesEditorEvent } from "../types"; import { configElementStyle } from "./config-elements-style"; const cardConfigStruct = struct({ @@ -20,6 +22,7 @@ const cardConfigStruct = struct({ entity: "string?", name: "string?", theme: "string?", + show_forecast: "boolean?", }); @customElement("hui-weather-forecast-card-editor") @@ -46,6 +49,10 @@ export class HuiWeatherForecastCardEditor extends LitElement return this._config!.theme || ""; } + get _show_forecast(): boolean { + return this._config!.show_forecast || true; + } + protected render(): TemplateResult { if (!this.hass || !this._config) { return html``; @@ -61,28 +68,36 @@ export class HuiWeatherForecastCardEditor extends LitElement "ui.panel.lovelace.editor.card.config.required" )})" .hass=${this.hass} - .value="${this._entity}" + .value=${this._entity} .configValue=${"entity"} - .include-domains=${["weather"]} - @change="${this._valueChanged}" + .includeDomains=${["weather"]} + @change=${this._valueChanged} allow-custom-entity > - - +
    + + +
    + Show forecast
    `; } @@ -101,7 +116,8 @@ export class HuiWeatherForecastCardEditor extends LitElement } else { this._config = { ...this._config, - [target.configValue!]: target.value, + [target.configValue!]: + target.checked !== undefined ? target.checked : target.value, }; } } diff --git a/src/panels/lovelace/entity-rows/hui-weather-entity-row.ts b/src/panels/lovelace/entity-rows/hui-weather-entity-row.ts index 794630aa76..dc1e526322 100644 --- a/src/panels/lovelace/entity-rows/hui-weather-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-weather-entity-row.ts @@ -14,11 +14,11 @@ import { getWeatherUnit, weatherIcons, weatherImages, + getSecondaryWeatherAttribute, } from "../../../data/weather"; import { HomeAssistant, WeatherEntity } from "../../../types"; import { EntitiesCardEntityConfig } from "../cards/types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; -import "../components/hui-warning"; import { LovelaceRow } from "./types"; @customElement("hui-weather-entity-row") @@ -77,95 +77,13 @@ class HuiWeatherEntityRow extends LitElement implements LovelaceRow { `}
    - ${!UNAVAILABLE_STATES.includes(stateObj.state) - ? this._getSecondaryAttribute(stateObj) - : ""} + ${getSecondaryWeatherAttribute(this.hass!, stateObj)}
    `; } - private _getSecondaryAttribute(stateObj: WeatherEntity): string | undefined { - const extrema = this._getExtrema(stateObj); - - if (extrema) { - return extrema; - } - - let value: number; - let attribute: string; - - if ( - stateObj.attributes.forecast?.length && - stateObj.attributes.forecast[0].precipitation !== undefined && - stateObj.attributes.forecast[0].precipitation !== null - ) { - value = stateObj.attributes.forecast[0].precipitation!; - attribute = "precipitation"; - } else if ("humidity" in stateObj.attributes) { - value = stateObj.attributes.humidity!; - attribute = "humidity"; - } else { - return undefined; - } - - return ` - ${this.hass!.localize( - `ui.card.weather.attributes.${attribute}` - )} ${value} ${getWeatherUnit(this.hass!, attribute)} - `; - } - - private _getExtrema(stateObj: WeatherEntity): string | undefined { - if (!stateObj.attributes.forecast?.length) { - return undefined; - } - - let tempLow: number | undefined; - let tempHigh: number | undefined; - const today = new Date().getDate(); - - for (const forecast of stateObj.attributes.forecast!) { - if (new Date(forecast.datetime).getDate() !== today) { - break; - } - if (!tempHigh || forecast.temperature > tempHigh) { - tempHigh = forecast.temperature; - } - if (!tempLow || (forecast.templow && forecast.templow < tempLow)) { - tempLow = forecast.templow; - } - if (!forecast.templow && (!tempLow || forecast.temperature < tempLow)) { - tempLow = forecast.temperature; - } - } - - if (!tempLow && !tempHigh) { - return undefined; - } - - const unit = getWeatherUnit(this.hass!, "temperature"); - - return ` - ${ - tempHigh - ? ` - ${this.hass!.localize(`ui.card.weather.high`)} ${tempHigh} ${unit} - ` - : "" - } - ${tempLow && tempHigh ? " / " : ""} - ${ - tempLow - ? ` - ${this.hass!.localize(`ui.card.weather.low`)} ${tempLow} ${unit} - ` - : "" - } - `; - } - static get styles(): CSSResult { return css` .attributes { diff --git a/src/translations/en.json b/src/translations/en.json index 26ddad1a5e..81f6e23278 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1907,7 +1907,8 @@ "warning": { "attribute_not_found": "Attribute {attribute} not available in: {entity}", "entity_not_found": "Entity not available: {entity}", - "entity_non_numeric": "Entity is non-numeric: {entity}" + "entity_non_numeric": "Entity is non-numeric: {entity}", + "entity_unavailable": "{entity} is currently unavailable" }, "changed_toast": { "message": "The Lovelace UI configuration for this dashboard was updated, refresh to see changes?", diff --git a/src/types.ts b/src/types.ts index 94672e5d4f..6a42dce227 100644 --- a/src/types.ts +++ b/src/types.ts @@ -259,6 +259,7 @@ interface ForecastAttribute { templow?: number; precipitation?: number; humidity?: number; + condition?: string; } export type WeatherEntity = HassEntityBase & { From a9d927551c3df70da39577fa2d10e9458fd72472 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 22 Apr 2020 12:16:03 +0200 Subject: [PATCH 36/36] Bumped version to 20200422.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e12ff412a7..1ca66681c8 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20200418.0", + version="20200422.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors",